1. 程式人生 > >第四章小結

第四章小結

工作 字符數 比較 地方 在線 next 規律 lose 包含

第四章小結

本章主要學了串、數組和廣義表

串的總結:

定義:

串(string或字符串)是由0個or多個字符有限序列

串的長度:串中字符的數目n

空串VS空格串:0個字符的串稱為空串,一個或者多個空格組成的串“ ”稱為空格串

主串:包含子串的串

模式(子串):串中任意個連續的字符組成的子序列

判斷兩串相等:當且僅當兩串長度相等+各個對應位置的字符都相等

串的存儲結構:鏈式和順序

順序存儲,註意:C語言中,存在Heap(堆)的自由存儲區域,可以為每一個新產生的串動態分配一塊實際串長所需的存儲空間,若分配成功,則返回一個指向起始地址的指針,作為串的基址---又稱:串的堆式順序存儲結構

鏈式存儲:依然是優越在插入與刪除操作的方便性(在找到目的地址後比較)

串的模式匹配算法:

首先學的是BF算法和KMP算法

BF算法的原理:

口語化文字分析:就是從串的某一個字符與模式(子串)一個一個比較,一般都是從第一個字符開始,不過可以指定主串中的查找的起始位置pos

算法描述:

int Index_BF(SString S , SString T , int pos)
{/*
模式T在主串S中第pos個字符開始第一次出現的位置。若不存在,
則返回值為0,其中T為非空,1<=pos && pos <= S.length */ i = pos; j = 1;//初始化 while(i <= S.length && j <= t.length)//兩個串均為比較到串尾 { if(S.ch[i]==T.ch[i])//繼續比較後續的字符 { ++i ; ++j;} else{ i=i-j+2 ; j=1; }//指針後退重新開始匹配 } if(j>T.length ) return i-T.length;//匹配成功 else return 0;//匹配失敗 }

BF算法的優勢在於匹配過程便於理解,且在一些場合利用較高(每一趟不成功的匹配都發生在模式串的第一個字符與主串中的相應的字符比較,時間復雜度為:O(m+n)),但是當匹配失敗的時候,主串的指針 i 總是要回溯到 i-j+2 的位置,且其在另外一種場合則利用率低(每趟不成功都發生在模式串的最後一個字符與主串中的相應的字符比較,時間復雜度為:O(m*n))  

KMP算法的原理:

時間復雜度是O(n+m)

這個真的是個大頭,看著令人頭大

技術分享圖片

註:為什麽第一位要用-1:假若之前有一個地方不匹配,則應該跳next數組,跳到下標為0處,但是這樣就變成死循環了,為防止死循環,我們應該退一步,將next數組的第0個賦值為-1 ——> 將整個next數組向後移——>就不會變成死循環了

所以我們要更改next函數

技術分享圖片
void xiuzhengnext(string pstring, int *next)
{//設計一個函數next,來修正next的數值
    next[0] = -1;//表示模式串的開頭,為-1,否則會錯位
    int j = 0, k = -1; 
    int plen = pstring.length();//模式串的長度     
    char *p = jg(pstring);//模式串的字符數組
    while (j < plen)
    {
        if(k == -1 || p[j] == p[k])
        {
            k++;
            j++;
            next[j] = k;/*next數組存放著已匹配的子串中最長的前後綴,
            next[j]  表示p[0]-p[j] 子串中最長的前後綴長度*/ 
        }
        else{
            k = next[k]; //k回溯到模式串的開頭 
        }
     } 
    
}
View Code

所以就寫了下面這個KMP的一個函數

技術分享圖片
int kmp( string s, string pstring)
{
    int *next = new int [pstring.length()];
    xiuzheng_next(pstring,next);//得到 next[]數組
    char *c = jg(s);
    char *p = jg(pstring);
    //轉換字符串為字符數組 
    int i=0,j=0;
    int pos = 0;
    while( i<=s.length()|| j<=pstring.length() )
    {
        if(j ==-1 || c[i] == p[j]){
            i++;
            j++;
            
        }
        else{
            j = next[j];//
        }
                    /* 
                    (1)有著最長前後綴的時候,主串與模式串在主串s[j]的位置(模式串最長後綴後一位)
                    不匹配的時候の 時候,s[j]將會與模式串的最長前後綴的後一位進行比較
                    (2)沒有最長前後綴的時候,整個模式串後移一位   */

          
        if(j == pstring.length()){//匹配成功 
            pos = i-j+1;
            break;
        } 
        
    }
        return pos;
 } 
View Code

然後我們學習了數組

當然,我們在數組的上面,給我的理解主要是運用在矩陣那一方面

定義:數組是由類型相同的數據元素構成的有序集合,每個元素稱為數組元素,每個元素受n(n>=1)個線性關系約束。

數組一般不做插入或刪除的工作,因此用順序存儲結構來表示數組比較合適

行序為主序:Basic Pascal Java 和C

列序為主序:FORTRAN

有關二維數組的任一元素的存儲空間位置:LOC(I,J)=LOC(0,0)+(N*I+J)L;

推廣到n維(我打不出來,於是就決定放照片!)

技術分享圖片

一個矩陣即一個三維數組,包括矩陣的行、列,非零元素的總個數。然後才是裏面的具體數值。

特殊的矩陣壓縮:對稱+三角+對角+稀疏矩陣

廣義表純粹就是自己看了看,首先看了個圖,就覺得跟樹挺像的,其他的還要慢慢看

關於本周作業

我居然看懂了KMP算法,當然問了好幾個同學,然後是AI那道題,我也覺得挺喜歡的,因為更加貼近生活?

AI那道題就是先把大方向捋順,先將題目的需求列出來,然後在主函數中將接口函數寫出,最後再一點一點的將接口對應的函數補全

本周心得:

由於老師帶著我們一起打了AI那道大題,讓我對代碼又有了興趣和信心,而且最近看了比較多的ctf題,想想還是要認真打打代碼hhh,好好學習代碼。

希望以後,老師能經常帶著我們打一些題目,比如通過微信進行指導hhh,雖然可能很多同學不會在線hh,但是總之,本周感覺收獲很多,心態也更加的好了,希望下周繼續努力

周周有進步

關於作業的一些思考+解題過程我就先不放在這裏了,因為這次要晚一點才能寫完作業,我還是先總結再刷題hhh

下周目標:

當然是跟著老師繼續努力認真的學習hhh,然後保持著良好心態,並且經常看一些代碼來熟練的找出規律來應對一些web題

第四章小結