データ構造_シリアル_チェーンテーブルをストレージ構造としてKMPアルゴリズムを実現するC++実装

4843 ワード

これを書くのに長い間悩んでいたので、いつもある部分に問題が発生します.まず、シリアルの終了フラグを処理する問題では、他の判断条件と衝突して早期に終了することが多く、主シリアルとモードシリアルの状況にかかわらず結果は常にsucceedであり、単一サイクルチェーンテーブルにリンクするなど、いくつかの方法を試みたが、効果は常に理想的ではなかった.その後、一時newの変数を思いつき、使い終わってからdeleteを落とす.その結果、deleteを1つ多く書いたので、いつもエラーを報告していたが、ReMove関数ではdeleteが落ちていることに気づいた.それからGetNext()とKMP()の処理には少し問題があり、いくつかの細部が処理されていない.それから紙の上でシミュレーションをして、ゆっくりと調整して、貼って分かち合って、もし間違いがあれば、指摘を歓迎します.
"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");
	}

}