データ構造_シリアル_チェーンテーブルをストレージ構造としてKMPアルゴリズムを実現するC++実装
4843 ワード
これを書くのに長い間悩んでいたので、いつもある部分に問題が発生します.まず、シリアルの終了フラグを処理する問題では、他の判断条件と衝突して早期に終了することが多く、主シリアルとモードシリアルの状況にかかわらず結果は常にsucceedであり、単一サイクルチェーンテーブルにリンクするなど、いくつかの方法を試みたが、効果は常に理想的ではなかった.その後、一時newの変数を思いつき、使い終わってからdeleteを落とす.その結果、deleteを1つ多く書いたので、いつもエラーを報告していたが、ReMove関数ではdeleteが落ちていることに気づいた.それからGetNext()とKMP()の処理には少し問題があり、いくつかの細部が処理されていない.それから紙の上でシミュレーションをして、ゆっくりと調整して、貼って分かち合って、もし間違いがあれば、指摘を歓迎します.
"head.h"
"main.cpp"
"head.h"
#include<iostream>
using namespace std;
class NODE
{
public:
NODE();
char ch;
NODE * succ;//
NODE * next;// ; " "
};
NODE::NODE()
{
succ=next=NULL;
}
class STRING
{
public:
STRING();
void GetMainString();
void GetSubstring();
void KMP();
void Print();
private:
void GetNext();
void ReMove(NODE *);
void GetLeftString(NODE *);
NODE *head1,*p1,*end1,*head2,*p2,*end2;
//end1 end2
};
STRING::STRING()
{
end1=head1=p1=end2=head2=p2=NULL;
}
void STRING::GetMainString()//
{
cout<<"GetMainString Called !"<<endl<<endl;
char ch;
if(head1!=NULL)//
{
ReMove(head1);
head1=NULL;
// delete end1;
// end1 , ReMove p==NULL, end1
}
while(cin>>ch)
{
if(head1==NULL)
{
head1=new NODE;
head1->ch=ch;
head1->next=head1;
p1=head1;
}
else
{
p1->succ=new NODE;
p1->succ->ch=ch;
p1->succ->next=p1;
p1=p1->succ;
}
}
if(head1!=NULL)
{
p1->succ=end1=new NODE;//
}
cin.clear();
}
void STRING::GetSubstring()//
{
cout<<"GetSubString Called !"<<endl<<endl;
char ch;
if(head2!=NULL)
{
ReMove(head2);
head2=NULL;
// delete end2;
}
while(cin>>ch)
{
if(head2==NULL)
{
head2=new NODE;
head2->ch=ch;
p2=head2;
}
else
{
p2->succ=new NODE;
p2=p2->succ;
p2->ch=ch;
}
}
if(head2!=NULL)
{
p2->succ=end2=new NODE;
}
cin.clear();
}
void STRING::KMP()//KMP
{
cout<<"KMP Called !"<<endl<<endl;
if(head1==NULL||head2==NULL)//
{
cout<<"Failed !"<<endl<<endl;
}
GetNext();// next" "
p1=head1;
p2=head2;
while(p1!=end1&&p2!=end2)
{
if(p2==NULL||p1->ch==p2->ch)
{
p1=p1->succ;
if(p2==NULL)
p2=head2;
else
p2=p2->succ;
}
else
{
p2=p2->next;
}
}
if(p2==end2)//
{
cout<<"Succeed ! The Left Of The String is = ";
GetLeftString(p1);
}
else
{
cout<<"Failed !"<<endl<<endl;
}
}
void STRING::Print()//
{
cout<<"Print Called !"<<endl<<endl;
if(head1==NULL)
{
cout<<"No Data In MainString !"<<endl<<endl;
}
else
{
cout<<"MainString = ";
p1=head1;
while(p1!=end1)
{
cout<<p1->ch;
p1=p1->succ;
}
cout<<endl<<endl;
}
if(head2==NULL)
{
cout<<"No Data In SubString !"<<endl<<endl;
}
else
{
cout<<"SubString = ";
p2=head2;
while(p2!=NULL)
{
cout<<p2->ch;
p2=p2->succ;
}
cout<<endl<<endl;
}
}
void STRING::GetNext()// next
{
p1=head2;
p2=head2->next=NULL;
while(p1->succ!=end2)
{
if(p2==NULL||p1->ch==p2->ch)
{
p1=p1->succ;
if(p2==NULL)
p2=head2;
else
p2=p2->succ;
if(p2!=p2->next)
p1->next=p2;
else
p2=p2->next;
}
else
{
p2=p2->next;
}
}
}
void STRING::GetLeftString(NODE *p)//
{
while(p!=end1)
{
cout<<p->ch;
p=p->succ;
}
cout<<endl<<endl;
}
void STRING::ReMove(NODE *p)//
{
if(p==NULL)
return;
else
{
ReMove(p->succ);
delete p;
}
}
"main.cpp"
#include<iostream>
#include"head.h"
using namespace std;
int main()
{
char choice;
STRING str;
while(1)
{
cout<<"Your Choice Please ?"<<endl<<endl
<<"1 . SetMainString"<<endl
<<"2 . SetSubString"<<endl
<<"3 . KMP"<<endl
<<"4 . Print"<<endl
<<"5 . Quit"<<endl<<endl;
cin>>choice;
system("cls");
switch(choice)
{
case '1':
str.GetMainString();
break;
case '2':
str.GetSubstring();
break;
case '3':
str.KMP();
cin.get();
cin.get();
break;
case '4':
str.Print();
cin.get();
cin.get();
break;
case '5':
return 0;
break;
default:
cout<<"No Such Choice !"<<endl<<endl;
cin.get();
cin.get();
break;
}
system("cls");
}
}