String 在数组中找到第一个匹配的字符串?

String 在数组中找到第一个匹配的字符串?,string,algorithm,search,String,Algorithm,Search,我已经写了一个简单的字符串搜索算法,我想改进一下,我应该从哪里开始呢 我想更改简单算法的原因是: pool似乎是一个大数组 toSearch中的字符串似乎是长字符串 代码如下: var pool []string = []string{"st", "se", "go", "es", "per", "123", "abcd", "e", "2"} func search(aStr string) (index int) { for i, s := range pool {

我已经写了一个简单的字符串搜索算法,我想改进一下,我应该从哪里开始呢

我想更改简单算法的原因是:

  • pool
    似乎是一个大数组
  • toSearch
    中的字符串似乎是长字符串
  • 代码如下:

    var pool []string = []string{"st", "se", "go", "es", "per", "123", "abcd", "e", "2"}
    
    func search(aStr string) (index int) {
        for i, s := range pool {
            if strings.Contains(aStr, s) {
                return i
            }
        }
    
        return -1
    }
    
    func main() {
        toSearch := []string{"string", "search", "algorithm", "best", "performance"}
        for _, s := range toSearch {
            idx := search(s)
            fmt.Printf("search %s in %d(%s)\n", s, idx, pool[idx])
        }
    }
    

    您可以使用一个特殊字符将toSearch数组中的所有字符串连接起来,比如说
    $
    ,那么您的搜索字符串将变成
    “string$search$algorithm$best$performance”
    ,并且您可能需要分配一个数组,如果找到匹配项,该数组将保留您当前所在字符串的记录

    恐怕对于池数组,您必须逐个搜索上面创建的字符串

    降低复杂性的方法之一是对池数组的每个元素使用线性时间模式匹配算法,而不是您使用的二次时间模式匹配算法

    我已经发布了3个线性时间算法来搜索给定字符串中的模式,其中2个是确定性的,最后一个是非确定性的

    一个确定性的、更标准的解决方案是使用,尽管理解起来有点复杂,但您可以很容易地找到在线实现它的代码。它是线性时间,其中m是输入字符串的长度,n是模式的长度

    另一种确定性算法,也是我最喜欢的算法之一,就是Z算法 更容易理解和实现,也是线性时间,它构造了所谓的Z数组,即用于轻松计算字符串中的模式匹配。您可以在上查看此链接

    如果您想使用非确定性算法,您可以使用,它需要散列(特别是滚动散列的概念),并且它是最容易实现的,并且是线性时间。如果您检查使用散列得到的字符串是否正确,或者是否由于冲突,那么它也可以是确定性的,但在最坏的情况下,如果您使rabin-karp算法具有确定性,那么它会给出二次复杂度

    我用下面的Z算法编写了一个C++代码:

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    string s, temp;
    int n, Z[1000];
    int toSearchSize, poolSize, lookUpIndex[1000];
    string toSearch[5] = {"string", "search", "algorithm", "best", "performance"};
    string pool[9] = {"st", "se", "go", "es", "per", "123", "abcd", "e", "2"};
    
    void joinString(){
        int idx = 0;
        for(int i = 0;i < toSearchSize;i++){
            s += toSearch[i];
            for(int j = idx;j <= idx+toSearch[i].size();j++) lookUpIndex[j] = i;
            s += "$";
            idx += toSearch[i].size()+1;
        }
        temp = s;
    }
    
    void zval(){
        int L = 0, R = 0;
        for(int i = 1;i<n;i++){
            if(i > R){
                L = R = i;
                while(R < n && s[R-L] == s[R]) R++;
                Z[i] = R-L;R--;
            }else{
                int b = R-i+1;
                if(Z[i-L] < b) Z[i] = Z[i-L];
                //else if(Z[i-L] > b) Z[i] = b;
                else{
                    L = i;
                    while(R < n && s[R-L] == s[R]) R++;
                    Z[i] = R-L;R--;
                }
            }
        }
    }
    
    int main(){
        toSearchSize = 5, poolSize = 9;
        joinString();
    
        for(int i = 0;i < poolSize;i++){
            for(int j = 0;j < n;j++) Z[j] = 0;
            s = pool[i] + temp;
            n = s.size();
            zval();
    
            for(int j = pool[i].size();j < n;j++){
                if(Z[j] >= pool[i].size()){
                    cout << "Match Found for : " << pool[i] << " in string : " << toSearch[lookUpIndex[j]] << endl;
                }
            }
        }
    
        return 0;
    }
    

    链接到Ideone上的解决方案:

    您是否搜索第一个匹配项?我是池中字符串的索引吗?@userunknown是的,也许我应该用你的建议更改问题。你应该为编程添加一个标记lanugage@cricket_007我认为这只是一个算法问题,如果你能用python,ruby,perl等等给我答案,这也没关系。那么,你能在你的问题上再多描述一下算法的要求是什么吗?是否要在
    中从
    到搜索
    查找字符串?
    Match Found for : st in string : string
    Match Found for : st in string : best
    Match Found for : se in string : search
    Match Found for : go in string : algorithm
    Match Found for : es in string : best
    Match Found for : per in string : performance
    Match Found for : e in string : search
    Match Found for : e in string : best
    Match Found for : e in string : performance
    Match Found for : e in string : performance