字符串匹配算法第一篇——暴力匹配

字符串匹配是一项重要的内容,本处我们讨论的字符串匹配是完全匹配,也就是找出子字符串在父字符串中的匹配位置。

例如:父字符串:EDGRNGIGEDEDGEDGLGDEDG,子字符串:EDG;则需要知道“EDG”在父字符串中的位置。先上代码:

 1 //使用暴力穷举法完成字符串匹配算法 
 2 # include "iostream"
 3 #include"string"
 4 #include"vector"
 5 using namespace std;
 6 vector<int>& BFmatch(string & , string & , vector<int>&);
 7 void ShowPos(vector<int>& );
 8 int main()
 9 {
10     string ModelStr, SonStr;
11     vector<int> pos;
12     cout << "请输入待匹配字符串:";
13     cin >> ModelStr ;
14     cout << endl;
15     cout << "请输入子字符串:";
16     cin >> SonStr;
17     cout << endl;
18     BFmatch(ModelStr, SonStr, pos);
19     ShowPos(pos);
20     system("pause");
21 }
22 vector<int>& BFmatch(string & ModelStr, string & SonStr,vector<int>& pos)
23 {
24     for (int i = 0; i < ModelStr.size(); i++)
25     {
26         int k = 0;
27         for (int j = i; k < SonStr.size(); j++, k++)
28         {
29             if (SonStr[k] == ModelStr[j])
30                 continue;
31             else
32                 break;
33         }
34         if (k == SonStr.size())
35             pos.push_back(i);
36     }
37     return pos;
38 }
39 void ShowPos(vector<int>& pos)
40 {
41     if (pos.size() != 0)
42     {
43         cout << "the first position of MatchingStr:";
44         for (int i = 0; i < pos.size(); i++)
45         {
46             cout << pos[i] << "\t";
47         }
48         cout << endl;
49     }
50     else
51         cout << "no such string!" << endl;
52 }

需要说明的是:函数BFmatch的返回类型为vector<int>&,返回类型为引用类型。需要理解的是为什么这里返回来的是vector<int>& 类型?

        我们需要明确的一点是:函数的返回类型是:函数返回值的类型!!!这句话很重要。返回值是pos变量,pos变量类型是传递在形参里面;而在形参中pos的类型是vector<int>&。这里为什么是vector<int>&类型,可能我们会想到说是我们的初衷是返回一个存储匹配位置的向量,空间比较大,采用这种方式可以节省空间,采用值传递的方式不节省开销。还有没有别的解释呢?

        的确,我们假设不考虑这个空间节省的问题。甚至不传递pos变量,最后让这个函数返回一个局部变量,最终将这个局部变量赋值给main函数中的pos,这当然也是可以的,但是这其中不仅仅带来了空间开销,更重要的是程序设计理念。

         这个设计里面是:一个函数的名字和形参,从功能和接口的角度看,我们希望包含:程序名、输入接口,输出接口。也就是我们希望每个函数的返回值(也就是我们的输出)直接反映在函数体抬头。(在opencv的库中大量使用了这种手法)。也就是:函数名,输入端子,输出端子 来描述函数是一种更为科学的表述方式。而我们要想将输出端子作为一种公共接口,自然不能使用局部变量的方式,局部变量只在本作用域起作用。因此我们需要使用一种公共接口的方式来定义输出端子,而采用引用传递就是一种公共接口的实现方式(当然还有其他方式)。

         因此,在后续的程序设计中,考虑函数名,输入接口,输出接口的方式来看待程序设计,是一种更为高级的抽象方式。

 

posted @ 2019-08-24 11:16  少年π  阅读(823)  评论(0编辑  收藏  举报