国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

字符串查找算法及原理

enda / 878人閱讀

摘要:字符串和中,存放必須為字符串長(zhǎng)度例在中要從下標(biāo)處開(kāi)始查找說(shuō)明標(biāo)準(zhǔn)算法中,為研究方便,中存放的為各自字符串長(zhǎng)度。則計(jì)算字符串的哈希值公式如下,如圖算法導(dǎo)論上提供的示例圖算法二算法許多算法可以完成這個(gè)任務(wù),算法簡(jiǎn)稱是最常用的之一。

面試題: 判斷字符串是否在另一個(gè)字符串中存在?

面試時(shí)發(fā)現(xiàn)好多人回答不好, 所以就梳理了一下已知的方法, 此文較長(zhǎng), 需要耐心的看下去。從實(shí)現(xiàn)和算法原理兩方面解此問(wèn)題, 其中有用PHP原生方法實(shí)現(xiàn)也有一些業(yè)界大牛創(chuàng)造的算法。

實(shí)現(xiàn) 方法一: 語(yǔ)言特性-內(nèi)置函數(shù)

函數(shù) 描述 版本
strpos 查找字符串首次出現(xiàn)的位置 PHP 4, PHP 5, PHP 7
stripos 查找字符串首次出現(xiàn)的位置(不區(qū)分大小寫) PHP 5, PHP 7
strrpos 計(jì)算指定字符串在目標(biāo)字符串中最后一次出現(xiàn)的位置 PHP 4, PHP 5, PHP 7
strripos 計(jì)算指定字符串在目標(biāo)字符串中最后一次出現(xiàn)的位置(不區(qū)分大小寫) PHP 5, PHP 7
mb_strpos 查找字符串在另一個(gè)字符串中首次出現(xiàn)的位置 PHP 4 >= 4.0.6, PHP 5, PHP 7
strstr 查找字符串的首次出現(xiàn) PHP 4, PHP 5, PHP 7
stristr strstr() 函數(shù)的忽略大小寫版本 PHP 4, PHP 5, PHP 7
substr_count 計(jì)算字串出現(xiàn)的次數(shù) PHP 4, PHP 5, PHP 7
方法二: 語(yǔ)言特性-正則匹配

函數(shù) 描述 版本
preg_match 執(zhí)行匹配正則表達(dá)式 PHP 4, PHP 5, PHP 7
preg_match_all 執(zhí)行一個(gè)全局正則表達(dá)式匹配 PHP 4, PHP 5, PHP 7
方法三: 語(yǔ)言特性-字符串分割
= 2 ? true : false;
}

// strtok 可以么?
// 在分割字符串時(shí),split()與explode()誰(shuí)快?
函數(shù) 描述 版本
strtok 標(biāo)記分割字符串 PHP 4, PHP 5, PHP 7
explode 使用一個(gè)字符串分割另一個(gè)字符串 PHP 4, PHP 5, PHP 7
split 用正則表達(dá)式將字符串分割到數(shù)組中 PHP 4, PHP 5
mb_split 使用正則表達(dá)式分割多字節(jié)字符串 PHP 4 >= 4.2.0, PHP 5, PHP 7
preg_split 通過(guò)一個(gè)正則表達(dá)式分隔字符串 PHP 4, PHP 5, PHP 7
方法四: 很暴力的查找
 $aLen) {
        return -1;
    }
    
    $data = [];
    
    $aLastIndex = -1;
    $bStartIndex = 0;
    
    for($ai = 0; $ai < $aLen; $ai++) {
        $av = $aArr[$ai];
        
        $exists = false;
        for($bi = $bStartIndex; $bi < $bLen; $bi++) {
            $bv = $bArr[$bi];

            if(($aLastIndex == -1 || $ai == ($aLastIndex + 1)) && $av == $bv) {
                $exists = true;
                break;
            }
            
            if ($aLastIndex != -1 && $ai == ($aLastIndex + 1) && $av != $bv) {
                break;
            }
        }
        
        if ($exists) {
            $aLastIndex = $ai;
            $bStartIndex = $bi + 1;
            array_push($data, [
                "value" => $av,
                "index" => $ai
            ]);
        } else {
            $aLastIndex = -1;
            $bStartIndex = 0;
            $data = [];
        }
        
        if ($exists && $bLen == $bStartIndex) {
            break;
        }
    }
    
    if(!empty($data) && count($data) == $bLen) {
        $begin = array_shift($data);
        return $begin["index"];
    } else {
        return -1;
    }
}
方法五: 樸素算法(暴力查找)

方法六: 字符串查找算法-Rabin-Karp算法
#include 
#include 

using namespace std;

#define BASE 256
#define MODULUS 101

void RabinKarp(char t[], char p[])
{
    int t_len = strlen(t);
    int p_len = strlen(p);

    // 哈希滾動(dòng)之用
    int h = 1;
    for (int i = 0; i < p_len - 1; i++)
        h = (h * BASE) % MODULUS;

    int t_hash = 0;
    int p_hash = 0;
    for (int i = 0; i < p_len; i++)
    {
        t_hash = (BASE * t_hash + t[i]) % MODULUS;
        p_hash = (BASE * p_hash + p[i]) % MODULUS;
    }

    int i = 0;
    while (i <= t_len - p_len)
    {
         // 考慮到哈希碰撞的可能性,還需要用 memcmp 再比對(duì)一下
        if (t_hash == p_hash && memcmp(p, t + i, p_len) == 0)
            cout << p << " is found at index " << i << endl;

        // 哈希滾動(dòng)
        t_hash = (BASE * (t_hash - t[i] * h) + t[i + p_len]) % MODULUS;

        // 防止出現(xiàn)負(fù)數(shù)
        if (t_hash < 0)
            t_hash = t_hash + MODULUS;

        i++;
    }
}

int main()
{
    char t[100] = "It is a test, but not just a test";
    char p[10] = "test";
    
    RabinKarp(t, p);
    
    return 0;
}
 1,
        "e" => 2,
        "l" => 3,
        "o" => 4,
        "w" => 5,
        "r" => 6,
        "d" => 7,
    );

    for ($i = 0; $i < $len; $i++) {
        $hash .= $hash_table[$str{$i}];
    }

    return (int)$hash;
}

function rabin_karp($text, $pattern)
{
    $n = strlen($text);
    $m = strlen($pattern);

    $text_hash = hash_string(substr($text, 0, $m), $m);
    $pattern_hash = hash_string($pattern, $m);

    for ($i = 0; $i < $n-$m+1; $i++) {
        if ($text_hash == $pattern_hash) {
            return $i;
        }

        $text_hash = hash_string(substr($text, $i, $m), $m);
    }

    return -1;
}

// 2
echo rabin_karp("hello world", "ello");
方法七: 字符串查找算法-KMP
public class KMP {
    public static int KMPSearch(String txt, String pat, int[] next) {
        int M = txt.length();
        int N = pat.length();
        int i = 0;
        int j = 0;
        while (i < M && j < N) {
            if (j == -1 || txt.charAt(i) == pat.charAt(j)) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }
        if (j == N)
            return i - j;
        else
            return -1;
    }

    public static void getNext(String pat, int[] next) {
        int N = pat.length();
        next[0] = -1;
        int k = -1;
        int j = 0;
        while (j < N - 1) {
            if (k == -1 || pat.charAt(j) == pat.charAt(k)) {
                ++k;
                ++j;
                next[j] = k;
            } else
                k = next[k];
        }
    }


    public static void main(String[] args) {
        String txt = "BBC ABCDAB CDABABCDABCDABDE";
        String pat = "ABCDABD";
        int[] next = new int[pat.length()];
        getNext(pat, next);
        System.out.println(KMPSearch(txt, pat, next));
    }
}
方法八: 字符串查找算法-Boyer-Moore
public class BoyerMoore {
    public static void getRight(String pat, int[] right) {
        for (int i = 0; i < 256; i++){
            right[i] = -1;
        }
        for (int i = 0; i < pat.length(); i++) {
            right[pat.charAt(i)] = i;
        }
    }

    public static int BoyerMooreSearch(String txt, String pat, int[] right) {
        int M = txt.length();
        int N = pat.length();
        int skip;
        for (int i = 0; i <= M - N; i += skip) {
            skip = 0;
            for (int j = N - 1; j >= 0; j--) {
                if (pat.charAt(j) != txt.charAt(i + j)) {
                    skip = j - right[txt.charAt(i + j)];
                    if (skip < 1){
                        skip = 1;
                    }
                    break;
                }
            }
            if (skip == 0)
                return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        String txt = "BBC ABCDAB AACDABABCDABCDABDE";
        String pat = "ABCDABD";
        int[] right = new int[256];
        getRight(pat,right);
        System.out.println(BoyerMooreSearch(txt, pat, right));
    }
}
方法九: 字符串查找算法-Sunday
public class Sunday {
    public static int getIndex(String pat, Character c) {
        for (int i = pat.length() - 1; i >= 0; i--) {
            if (pat.charAt(i) == c)
                return i;
        }
        return -1;
    }

    public static int SundaySearch(String txt, String pat) {
        int M = txt.length();
        int N = pat.length();
        int i, j;
        int skip = -1;
        for (i = 0; i <= M - N; i += skip) {
            for (j = 0; j < N; j++) {
                if (txt.charAt(i + j) != pat.charAt(j)){
                    if (i == M - N)
                        break;
                    skip = N - getIndex(pat, txt.charAt(i + N));
                    break;
                }
            }
            if (j == N)
                return i;
        }
        return -1;
    }
    public static void main(String[] args) {
        String txt = "BBC ABCDAB AACDABABCDABCDABD";
        String pat = "ABCDABD";
        System.out.println(SundaySearch(txt, pat));
    }
}
方法十: 字符串查找算法-BF算法(Brute Force)
#include   
#include   
#include   
  
int index_bf(char *s,char *t,int pos);  
int index_bf_self(char *s,char *t,int index);  
  
int main()  
{  
    char s[]="6he3wor"; //標(biāo)準(zhǔn)BF算法中,s[0]和t[0]存放的為字符串長(zhǎng)度。  
    char t[]="3wor";  
    int m=index_bf(s,t,2); //標(biāo)準(zhǔn)BF算法  
    printf("index_bf:%d
",m);  
    m=index_bf_self(s,t,2); //修改版BF算法,s和t中,不必再存放字符串長(zhǎng)度。  
    printf("index_bf_self:%d
",m);  
    exit(0);  
}  
  
/* 
字符串S和T中,s[0],t[0]存放必須為字符串長(zhǎng)度 
例:s[]="7hi baby!"  T[]="4baby"  index_bf(s,t,1); 
pos:在S中要從下標(biāo)pos處開(kāi)始查找T 
(說(shuō)明:標(biāo)準(zhǔn)BF算法中,為研究方便,s[0],t[0]中存放的為各自字符串長(zhǎng)度。) 
*/  
int index_bf(char *s,char *t,int pos)  
{  
    int i,j;  
    if(pos>=1 && pos <=s[0]-"0")  
    {  
        i=pos;  
        j=1;  
        while(i<=s[0]-"0"&&j<=t[0]-"0")  
        {  
            if(s[i]==t[j])  
            {  
                i++;  
                j++;  
            }  
            else   
            {  
                j=1;  
                i=i-j+2;  
            }  
            if(j>t[0]-"0")  
            {  
                return i-t[0]+"0";  
            }  
        }  
        return -1;  
    }  
    else   
    {  
        return -1;  
    }  
}  
  
/* 
修改版,字符串s和t中,不必再包含字符串長(zhǎng)度。 
例:s[]="hi baby"  t[]="baby"  index_bf_self(s,t,0); 
index:在s中,從幾號(hào)下標(biāo)開(kāi)始查找 
*/  
int index_bf_self(char *s,char *t,int index)  
{  
    int i=index,j=0;  
    while(s[i]!="