模式匹配(子串问题)

来源:互联网 发布:java写入word文件 编辑:程序博客网 时间:2024/05/17 08:06

B-F算法

就是暴力搜索,易于理解,效率不高

KMP算法

关键就是预处理NEXT数组,利用之前的失败信息减少主串匹配次数。不需要回溯是关键啦~


#include<iostream>
#include<string>
using namespace std;


template<class T>
class Node
{
private:
public:
        typedef struct pNode
{
pNode *pnext;
   pNode *ppre;
T data;
}plist;

plist *head;
#if 1
Node(){}
   Node(string data,int n)                        //构造函数 
   {              

    this->head = Create_list(data,n);
   }
#endif    
~Node(){}
       //输出链表数据 
void output()
{
plist *p;
p = this->head;
while(p != NULL)
{
cout << p->data <<" ";
p = p->pnext;
}
cout<<endl;


void replace_string(string pattern,string list)
{
int j;
int temp;
int next[100];
int len_list;
int len_next;


plist *new_head;
plist *list_head = new plist;
plist *temp_p;


//创建替换list链;
len_list = list.length();
list_head = Create_list(list,len_list);
new_head = this->head;
        
memset(next,0,sizeof(next));
len_next = cal_next(next,pattern);     //计算Next数组 

j = 0;
while(new_head != NULL)
{
//KMP
if(new_head->data == pattern[j])
{

if(j == len_next - 1)             //找到匹配模式
{
       temp = 0;//替换
temp_p = new_head;
while(temp != len_next)//找到要替换的节点的前一节点;
{
temp++;
temp_p = temp_p->ppre;
}


list_head = Create_list(list,len_list);//创建新的List链
temp_p->pnext = list_head;
list_head->ppre = temp_p;


temp_p = list_head;
//找list尾节点
while (temp_p->pnext != NULL)
{
temp_p = temp_p->pnext;


}
temp_p->pnext = new_head->pnext;   //替换链尾
if (new_head->pnext != NULL)
{
new_head->pnext->ppre = temp_p;
}

//cout<<"========================================="<<endl;
j = 0;
new_head = new_head->pnext;
}
else
{
j++;
new_head = new_head->pnext;
}
}
else
{
if(j == 0 || next[j - 1] == -1)
{
j = 0;                          //第一个元素或者无匹配前缀
new_head = new_head->pnext;
}
else
{
j = next[j - 1] + 1;//匹配前缀
}
}
 
          



}
}

protected:
//导入串S 
virtual plist *Create_list(string s,int count)

   int i;
plist *phead = new plist;
plist *temp;

phead->data = s[0];
temp = phead;

for(i = 1;i < count;i++)

{
plist *p =  new plist;
p->data = s[i];
temp->pnext = p;
p->ppre = temp;
temp = p; 


temp->pnext = NULL;   //链表尾处理 
phead->ppre = NULL;
return phead;

}
int  cal_next(int *next,string patt) //建立匹配表 
{
int i;
int j;
int len;

next[0] = -1;
len = patt.length();

j = 0;
for(i = 1;i < len;i++)
{
if(patt[i] == patt[j])
{
next[i] = j;
j++;
}
else 
if(patt[0] == patt[i])
   {
       next[i] = 0;
j = 1;    
   }
else
{
j = 0;
next[i] = -1;
}
}
#if 0
for(i = 0;i < len;i++)
{
cout<<next[i]<<" ";
   }
#endif
return len;
}

};
//************************************** 
//子类(有Bug) 
#if 0
template<class T>
class Seqlist:public Node<T>
{
public:
        typedef struct pNode
{
pNode *pnext;
pNode *ppre;
T data;
}plist;

plist *head = new plist;

   Seqlist(){}
   Seqlist(string data,int n)
   {
    this->head = this->Create_list(data,n);
   // Create_list(data,n);
   }
};
#endif
//***************************************** 
int main()
{
    int len;
string src = "cabaabcabaabcabaab";
string str = "abaab";
string list_str = "***";

len = src.length();
//Seqlist<char> p(str,len);
    Node<char> demo(src,len);

demo.output();
demo.replace_string(str,list_str);
demo.output();

    return 0;
}  

0 0
原创粉丝点击