串是由零個或多個字元組成的有限序列,又叫字串,也看成是線性結構,不過是內容受限的線性表結構。
子串與主串,串中任意個數的連續字元組成的子串行稱為該串的子串,,相應的,包含子串的串稱為主串。
子串位置指的是,子串的第乙個字母在主串中的位置。
關於串的比較,簡單來說,就是要當兩個串的長度相同而且每乙個位置上的字母都相同的時候,兩個串才是相等的。
同時,如果乙個串是另乙個串的子串,那麼顯然,主串比子串大。
具體的比較步驟是,從第一位開始,按照字典序順序,直到找到乙個位置,乙個串上的字母字典序大於另乙個對應位置的字母的字典序,這時候就產生了差異,字典序越往後的,字串越大。
下面來介紹子串的定位操作,也常被稱為串的模式匹配-,其通常表示為indexstinrg(string s,string t,int pos),pos用來指定尋找的位置。
其演算法設計通常有兩種演算法,bf(暴力求解)、kmp演算法(特點:速度快)。
bf:演算法思路:雙指標,乙個指標指向主串,乙個指標指向模式串,而且指標初始位置都是指向頭部的,當頭部相同的時候,記錄主串指標,下一步兩個指標同時後移,如果發現中間有一位不同,那麼就break掉,然後主串指標回溯到之前記錄的頭部指標,尋找成功條件是t串被讀完了,就是j指標==t串長度。
**實現如下:與課本不同的是,可以用pos變數來記錄位置,來避免數學計算上的抽象。
#include
#include
intmain()
}if(j==lent)
else
}else
}printf
("%d"
,pos+1)
;return0;
}
kmp演算法
其特點是主串指標不需要回溯,
涉及到next陣列的概念,next函式用於計算next值,表明當前模式中第j個字元與主串中的相應字元「失配」的時候,在模式中需要重新和主串中該字元進行比較的字元位置。同時涉及到一些概念,字首,字尾。
以abcde為例,
字首有a、ab、abc、abcd、但沒有abcde
字尾有bcde、cde、de、e
這樣的我們不難看成,某個串的字首,以最後乙個字元為界限,以第乙個字元為起點,找出其所有的組合(注意字元間的相對位置不能改變)。字尾同理。
next陣列的計算方法
簡單來說,就是先取字首,再取字尾,觀察字首串和字尾串相等的情況,一定要遍歷完所有的情況,找到最多的那個k值,包含有幾個字元,有幾個字元那麼k-1=幾個字元,當然特殊情況時,當模式串位於第一位的時候,這時候既沒有字首,也沒有字尾,那麼就是next[j]就是0,當位於第二位的時候,字首和字尾一定一樣,則時候為1.(限制與next陣列,不是nextval修正情況)
核心思想:以某個字元為分界線,找其最大公共字首和字尾,然後在每一次的kmp演算法中,在主串中找對應的綴串,我們需要注意的是,如果當乙個綴串匹配了,那麼這時候肯定存在另外乙個綴串是匹配的,也就是字尾的位置(因為每一次先找的都必然是先從字首開始找),而且為了不漏掉某種情況,我們需要找到的是最大公共前字尾,那麼這樣就必然不會漏掉某種情況(可以根據反證法來思考,如果漏掉了,會產生怎麼樣的結果?)這種匹配過程是一種動態的過程,在逐步匹配的過程中,將子串逐漸變成主串,當某一步不匹配的時候,根據next陣列來決定今後要幹什麼,與bf演算法最大的差異是,kmp演算法通過邏輯推理減少了很多不必要的判斷,把單個字元判斷變成了子串判斷。
下面是**剖析:
獲取next陣列,next陣列要幹的事情就是要找到最大公共綴串並且返回k值,通過大量資料驗證可知k值在i=1,和i=2的時候為0、1(非nextval),**如下:
void
get_next
(sstring t,
int next)
else
//不匹配了,j回溯,重新找匹配的值
}}
int
index_kmp
(sstring s,sstring t,
int pos)
else}if
(j>t[0]
)else
}
完整**如下:
#include
"stdio.h"
#include
"stdlib.h"
#include
"iostream"
#define true 1
#define false 0
#define ok 1
#define error 0
#define infeaslble -1
#define overflow -2
#define maxstrlen 255
//使用者可在255以內定義最大串長
typedef
unsigned
char sstring[maxstrlen+1]
;//0號單元存放串的長度
using
namespace std;
void
get_next
(sstring t,
int next)
else
//不匹配了,j回溯,重新找匹配的值}}
intindex_kmp
(sstring s,sstring t,
int pos)
else}if
(j>t[0]
)else
}int
main()
s[0]
=i-1
;// s[0]用於儲存主串中字元個數
ch=getchar()
;for
( i=
1;i<=maxstrlen&&
(ch!=
'\n'
);i++
)// 錄入模式串
t[0]
=i-1
;// t[0]用於儲存模式串中字元個數
pos=
index_kmp
(s,t,1)
; cout<}return0;
}
串的基本操作
include include include include define maxn 50 define ok 1 define error 0 typedef struct strnode snode void creat snode char 建立串 int getsubstr snode i...
串的基本操作
串的基本操作 前記 這一章課件裡主要講了串的屬性和一些常用的操作。課件裡面是通過偽 的方式來進行描述,這樣有利於同學們的理解,以及能夠適用於各種程式語言。下面就針對c 語言對這些基本操作做乙個具體的實現,大家在運用中可以參考。mystring.h ifndef mystring h define m...
串的基本操作
假設有串t s iphone 11 pro max?w pro strassign t,chars 賦值操作。把串t賦值為chars。strcopy t,s 複製操作。由串s複製得到串t。strempty s 判空操作。若s為空串,則返回true,否則返回false。strlength s 求串長。...