数组与串,串的实现,KMP,BF算法
數組是一種常用的數據結構,高級語言頭提供了支持數組的基本操作,而且數組也是構成其他數據結構的重要組成。
?數組是N個相同元素的構成的占用一塊地址連續的內存單元的有限序列。
? 數組的任一個元素都可以用在數組的位置來表示。
數組與線性表區別:數組符合線性結構的定義。
??? 但是區別是: 數組要求占用連續的地址空間,線性表的元素是不可分割的,數組可以是二維數組,數組主要操作是存放和讀取數據。
????
數組的實現機制:
????? 通常以字節為內部計數單位。對一個有N個數據元素的一維數組,設a0是下標為0的數組元素,Loc(a0)的內存單元地址,K是每一個數組元素的所需的字節個數,則數組中的任一個數據元素ai的內存單元地址為Loc(ai)可由下邊公司求出:
????? Loc(ai) = Loc(a0) + i*K;(0<=i<=N)
對于二維數組 M行N列
??? Loc(ai) = Loc(a00) +( i*N+j)*;(0<=i<=M)(0<=j<=N);
串:
??? 串是一種線性結構,與線性表的不同是:串的操作特點是依次操作若干數據元素,即一個子串。串可以使用順序結構和鏈式結構存儲。串的順序結構存儲空間和時間效率更高。模式匹配是串的很重要的一個操作。Brute-Force和KMP算法是兩種最經常使用的串的模式匹配算法。
? 串的基本概念:串是有個N>=0個字符組成的有限序列。一個串中任意個連續的字符組成的子序列稱為該串的子串。
? 串和字符不是一個概念:串是長度不定的字符序列的集合。字符只是一個字符。
串的抽象數據類型:
?? 串可以是由S0? , ...SN字符的組合。
操作的集合:
??? 初始化字符串;
??? 賦值字符串
??? 字符串長度
??? 比較字符
插入字符
刪除字符
取子串
查找子串
替換子串
C語言用字符數組存儲串。串的長度是不定,C語言解決長度不定的方法是在串的末尾自動添加一個'\0'作為字符串的結束標志。
???
串的存儲結構:
???? 串的存儲結構有順序存儲結構和鏈式存儲結構兩種。
??? 串的順序存儲結構:
???????? 與線性表的存儲結構相同,可以用一個字符類型的數組存儲串值。
????????????? 在串的順序存儲結構中,由于串的長度不定,因此要使用一種方法來辨別串的長度,一種是固定設置串長度,一種是使用\0作為串的結束標志。
串的鏈式存儲結構:
???? 串的鏈式鏈式結構就是把串值非別存放在構成鏈表的若干個結點的數據域上。串的鏈式結構分為單字符點連和塊鏈兩種。
??? 單字符鏈就是一個結點存儲一個字符。
塊鏈就是一個結點存儲幾個字符
?
?
串的基本實現方法:如同線性表的實現方法。
? 使用PHP代替:
???? <?php
/**
*
*串的實現
*/
header('Content-type: text/html;charset=utf-8');
class char {
?? ?public $size = 0; //元素個數而非數組大小
?? ?public $arr = array();
?? ?public $maxsize = 10; //數組大小
?? ?
?? ?
?? ?public function __construct($arr = array()) {
?? ??? ?$this->size = count($arr);
?? ??? ?$this->arr? = $arr;
?? ?}
?? ?
?? ?public function sizes() { return size;}
?? ?/**
?? ?*@param int 開始位置
?? ?*@param string 插入的字符串
?? ?*@return bool
?? ?*/
?? ?public function add($start,$str)? {
?? ??? ?$len = strlen($str);
?? ??? ?if(($start+$len) > $this->maxsize) {
?? ??? ??? ?return false;//插入數據超出字符大小
?? ??? ?} else {
?? ??? ??? ?for($i = $this->size-1;$i >= $len;$i--){
?? ??? ??? ??? ?$this->arr[$i+$len] = $this->arr[$i];
?? ??? ??? ?}
?? ??? ??? ?for($i = 0;$i<$len;$i++){
?? ??? ??? ??? ?$this->arr[$start+$i] = $str{$i};
?? ??? ??? ?}
?? ??? ??? ?$this->size = $this->size + $len;
?? ??? ?}
?? ?}
?? ?/**? 0,1,2,3,4,5,6
?? ?*刪除字符串
?? ?*@param int 開始位置
?? ?*@param int 刪除的個數
?? ?*/
?? ?public function delete($start,$len) {
?? ??? ?if(($start+$len) > $this->maxsize) {
?? ??? ??? ?return false;
?? ??? ?} else {
?? ??? ??? ?for($i=$start+$len;$i <=$this->size-1;$i++) {
?? ??? ??? ??? ?$this->arr[$i-$len] = $this->arr[$i];
?? ??? ??? ?}
?? ??? ??? ?$this->size = $this->size-$len;
?? ??? ??? ?for($i=$this->size-$len;$i <=$this->size-1;$i++) {
?? ??? ??? ??? ?unset($this->arr[$si]);
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?/**? 0,1,2,3,4,5,6
?? ?*取字符串
?? ?*@param int 開始位置
?? ?*@param int 刪除的個數
?? ?*/
?? ?public substr($start,$len) {
?? ??? ?for($i=0;$i<$len;$i++){
?? ??? ??? ?$str.=$this->arr[$i+$start];
?? ??? ?}
?? ??? ?return $str;
?? ?
?? ?}
?? ?
?? ?public function getstr() { echo implode('',$this->arr);}
?? ?/***************串的模式匹配***************/
?? ?
?? ?
}
$char = new char();
$char->add(0,'1');
$char->getstr();
?
?
串的模式匹配:
??? Brute-Force算法
????????? ?? BF算法是普通的模式匹配算法,BF算法的思想就是將目標串S的第一個字符與模式串P的第一個字符進行匹配,若相等,則繼續比較S的第二個字符和P的第二個字符;若 不相等,則比較S的第二個字符和P的第一個字符,依次比較下去,直到得出最后的匹配結果。
???? function BF($str,$t) {
?? ??? ?for($i=0;$i<strlen($str);$i++) {
?? ??? ??? ?for($j=0;$j<strlen($t);$j++) {
?? ??? ??? ??? ?if($str{$i}==$t{$j}) {$i++;} else { echo '<'.$i.'-'.$j.'>';$i = $i-$j; break;}
?? ??? ??? ?}
?? ??? ??? ?if($j==strlen($t)) return 'true';
?? ??? ?}
?? ??? ?return 'Flase';
?? ?}
function BF2($str,$t) {
?? ??? ?$i=$j=0;
?? ??? ?while($i<strlen($str)) {
?? ??? ??? ?$j=0;
?? ??? ??? ?while($str{$i} == $t{$j} && $j<strlen($t)) {
?? ??? ??? ??? ?$i++;
?? ??? ??? ??? ?$j++;
?? ??? ??? ?}
?? ??? ??? ?if($j==strlen($t)) return 'true';
?? ??? ?}
?? ??? ?return 'Flase';
?? ?}
KMP算法是對BF算法的優化
<?php
function indexNext($str){
??? $k = 0;?? //相同字符的位數
??? $j=1;
??? $nexts[0] = -1;? //是為了匹配當一個模式字符不予串匹配時的情況
??? $nexts[1] = 0;?? //當第二字符不匹配時 直接比較第一個字符
??? while($j<strlen($str)) {
??????? if($str{$j} == $str{$k}) {? //出現相同字符時
??????????? $nexts[$j+1] = $k+1;
??????????? $j++;
??????????? $k++;
??????? } else if($k==0) { //未出現相同字符 且前邊也未出現相同字符時
??????????? $nexts[$j+1] = 0;
??????????? $j++;
??????? } else { //前邊有相同字符,依次用當前字符比較是否與以前字符相同
??????????? $k = $nexts[$k];
?????????? ?
??????? }
??? }
??? return $nexts;
}
function KMP($str,$t) {
??? $nexts = indexNext($t);
??? print_r($nexts);
??? $i = 0;$j=0;
??? $k = 0;
??? while($i<strlen($str) && $j < strlen($t)) {
??????? $k ++;
??????? if($j == -1 || $str{$i} == $t{$j}) {//是為了匹配當一個模式字符不予串匹配時的情況及當$str{$i} == $t{$j}
??????????? $i++;$j++;
??????? } else {
?? ??? ?//當$str{$i} != $t{$j} 算出 真子串中相同的部分 真子串中相同的部分不用在比較
??????????? echo $i.'-'.$j.'*';
??????????? $j = $nexts[$j];
??????? }
?????? ?
??????? if($j==strlen($t)) {echo $k;return 'true';}
??? }
??? return 'false';
?? ?
}
echo KMP("BBC ABCDAB ABCDABCDABDE","ABCDABD");
print_R(indexNext("AAABCDAAABD"));
請問廣大牛人,這樣實習KMP算法對嗎?
轉載于:https://www.cnblogs.com/phplhs/p/4340793.html
總結
以上是生活随笔為你收集整理的数组与串,串的实现,KMP,BF算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [iOS] 建立与使用Framework
- 下一篇: 银行支付系统大小额(一代支付)、超级网银