1. 程式人生 > >串的基本操作(KMP演算法實現)

串的基本操作(KMP演算法實現)

#include <iostream>
#include <math.h>
using namespace std;

void StrAssign(char *T)
{
	char ch;
	int i=1;
	cout<<"Please enter a string.0 is exit."<<endl;
	while (cin>>ch&&ch!='0') {
		T[i++]=ch;
	}
	T[0]=i-1+'0';
	cout<<"Setting successfully!"<<endl;
}

int StrCopy(char *T,char *S)
{
	if (S[0]=='0') {
		cout<<"String is empty."<<endl;
		return -1;
	}
	else {
		for (int i=0;i<=S[i]-'0';i++) {
			T[i]=S[i];
			cout << T[i];
		}
		cout << endl;
	}
	cout<<"Copy successfuly!"<<endl;
	return 0;
}

int StrEmpty(char *S)
{
	if (S[0]=='0') {
		cout << "TRUE" << endl;
	}
	else {
		cout<<"FALSE"<<endl;
	}
	return 0;
}

int StrCompare(char *S,char * T)
{
	if (S[0]=='0'||T[0]=='0') {
		cout << "The string is empty." << endl;
		return -1;
	}
	int flag = 0;
	for (int i = 1; i <= S[0] - '0' && i <= T[0] - '0';i++) {
		if (S[i]==T[i])
			continue;
		else if (S[i]>T[i]) {
			flag = 1;
			break;
		}
		else if (S[i]<T[i]) {
			flag = -1;
			break;
		}
	}
	cout << flag << endl;
	return 0;
} 

int ClearString(char *S)
{
	if (S[0]=='0') {
		cout<<"The string is empty."<<endl;
		return -1;
	}
	for (int i=1;i<=S[0]-'0';i++) {
		S[i]=' ';
	}
	cout<<"Clear Successfully."<<endl;
	return 0;
}

int Concat(char *str,char *V) 
{
	if (str[0]=='0') return -1;
	int j,i;
	for (j=str[0]-'0'+1,i=1;i<=V[0]-'0';j++,i++) {
		str[j]=V[i];
	}
	cout<<"Connect successfully!"<<endl;
	str[0]=(str[0]-'0'+V[0]-'0')+'0';
	return 0;
}

int SubString(char *sub,char *str,int pos,int len)
{
	if (str[0]=='0') {
		cout<<"String is empty."<<endl;
		return -1;
	}
	else if (pos<1||pos+len-1>str[0]-'0') {
		cout<<"Position is illegal."<<endl;
		return -1;
	}
	for (int i = pos; i <= len;i++) {
		sub[i] = str[i];
		cout << sub[i];
	}
	cout << endl;
	return 0;
}

int KMP(char *s,char *v,int pos)
{
	if (s[0]=='0'||v[0]=='0') {
		cout<<"The string is empty."<<endl;
		return -1;
	}
	int i=1;
	int nextval[100];
	nextval[1]=0;
	int j=0;
	while (i<=v[0]-'0') {
		if (j==0||v[i]==v[j]) {
			i++;j++;
			if (v[i]!=v[j])
			nextval[i]=j;
			else
			nextval[i]=nextval[j];
		}
		else {
			j=nextval[j];
		}
	}
	i=pos;j=1;
	while (i<=s[0]-'0'&&j<=v[0]-'0') {
		if (j==0||s[i]==v[j]) {
			i++;j++;
		}
		else j=nextval[j];
	}
	if (j>v[0]-'0') {
		return i-(v[0]-'0');
	}
	return 0;
}

int PrintAll(char *str)
{
	for (int i=1;i<=str[0]-'0';i++) {
		cout<<str[i];
	}
	cout<<endl;
	return 0;
}

int Replace(char *s,char *t,char *v)
{
	if (s[0]=='0'||t[0]=='0'||v[0]=='0') {
		cout<<"The string is empty."<<endl;
		return -1;
	}
	int i = 1,pos;
	int len_cmp = (v[0] - '0') - (t[0] - '0');
	//cout << len_cmp << endl;
	int flag = 0;
	if (len_cmp>0) {//負數的邏輯值為真,所以需要加上大於小於號
		flag = 1;
	}
	else if (len_cmp<0) {
		flag = -1;
	}
	//cout << flag << endl;
	len_cmp = abs(len_cmp);
	while (i<s[0]-'0') {
		pos=KMP(s, t, i);
		if (flag<0) {
			for (int j = pos+(t[0]-'0'); j <= s[0] - '0';j++) {
				s[j - len_cmp] = s[j];
			}//移動
			for (int j = pos, k = 1; k <= v[0] - '0';k++,j++) {
				s[j] = v[k];
			}
			s[0] = (s[0] - '0' - len_cmp) + '0';//修改主串長短
		//	cout << s[0] - '0'<<endl;
		}
		else if (flag>0) {//如果v的長度大於t的長度,需要將主串s向後移動
			for (int j = s[0] - '0'; j >= pos; j--) {
				s[j + len_cmp] = s[j];
			}//move
			for (int j = pos, k = 1; k <= v[0] - '0';k++,j++) {
				s[j] = v[k];
			}
			s[0] = (s[0] - '0' + len_cmp) + '0';//修改主串長短
		}
		else if (flag==0){
			for (int j = pos, k = 1; k <= v[0] - '0';k++,j++) {
				s[j] = v[k];
			}
		}
		i = pos + (v[0] - '0');
		//cout << pos <<" "<< i << endl;
	}
	cout << "Substitute succeed." << endl;
	PrintAll(s);
	return 0;
	/*
	測試資料
	1
	1
	a0
	1
	0
	abababab0
	10
	c0

	1
	1
	ab0
	1
	0
	abababab0
	10
	c0

	1
	1
	ab0
	1
	0
	abababab0
	10
	abc0
	*/
}

int StrInsert(char *s,int pos,char *v)
{
	
	int v_len = v[0] - '0';
	for (int i = s[0] - '0'; i >= pos;i--) {
		s[i + v_len] = s[i];
	}
	for (int i = pos,j=1; j <= v_len;j++,i++) {
		s[i] = v[j];
	}
	s[0] = s[0] - '0' + v_len + '0';
	cout << "Insert successfully!" << endl;
	PrintAll(s);
	return 0;
}

int StrDelete(char *s,int pos,int len)
{
	if (pos<1||pos>s[0]-'0') {
		cout << "The position is illegal." << endl;
		return -1;
	}
	else if (len>s[0]-'0') {
		cout << "The length is too long." << endl;
		return -2;
	}
	for (int i = pos + len; i <= s[0] - '-';i++)
	{
		s[i-len] = s[i];
	}
	s[0] = s[0] - '0' - len + '0';
	cout << "Delete successfully!" << endl;
	PrintAll(s);
	return 0;
}

int main()
{
	cout<<"Please enter what you want to do.Zero is exit."<<endl
		<<"1.Setting a string."<<endl
		<<"2.Copy a string."<<endl
		<<"3.Is the string empty?"<<endl
		<<"4.Compare with the string A and string B."<<endl
		<<"5.Length of the string."<<endl
		<<"6.Clearing the string."<<endl
		<<"7.Connect two string."<<endl
		<<"8.Print the substring."<<endl
		<<"9.Search the substring."<<endl
		<<"10.Replace the substring."<<endl
		<<"11.Insert the substring."<<endl
		<<"12.Delete the substring."<<endl
		<<"13.Print string."<<endl;
	int n,pos,len,num;
	char T[100]={'0'},S[100]={'0'},V[100]={'0'};
	char sub[100]={'0'};
	while (cin>>n&&n) {
		switch (n) {
			case 1:
				cout << "Which do you want to set? T or S? Please enter the 1 or 0 to represent the diffirent string." << endl;
				cin >> num;
				if (num) {
					StrAssign(T);
				}
				else {
					StrAssign(S);
				}
				break;
			case 2:
				StrAssign(S);
				StrCopy(T,S);
				break;
			case 3:
				cout<<"The 1 represent the string T and the 0 represent the string S. Which string would you like to judge?"<<endl;
				cin>>num;
				if (num) {
					StrEmpty(T);
				}
				else {
					StrEmpty(S);
				}
				break;
			case 4:
				StrCompare(S,T);
				break;
			case 5:
				cout<<"The 1 represent the string T and the 0 represent the string S. Which length would you like to print?"<<endl;
				cin>>num;
				if (num) {
					cout<<T[0]-'0'<<endl;
				}
				else {
					cout<<S[0]-'0'<<endl;
				}
				break;
			case 6:
				cout<<"The 1 represent the string T and the 0 represent the string S. Which string would you like to clear?"<<endl;
				cin>>num;
				if (num) {
					ClearString(T);
				}
				else {
					ClearString(S);
				}
				break;
			case 7:
				cout<<"Please enter a string for connect."<<endl;
				StrAssign(V);
				Concat(S,V);
				break;
			case 8:
				cout << "Which string do you want to see? The string T or the string S? They are represent the 1 and 0." << endl;
				cin >> num;
				cout<<"Please enter the position and length."<<endl;
				cin>>pos>>len;
				if (num) {
					SubString(sub, T, pos, len);
				}
				else {
					SubString(sub, S, pos, len);
				}
				break;
			case 9:
				StrAssign(V);
				cout<<"Where do you want to start?"<<endl;
				cin >> num;
				cout<<KMP(S,V,num)<<endl;
				break;
			case 10:
				StrAssign(V);
				Replace(S,T,V);
				break;
			case 11:
				StrAssign(V);
				cout << "Please enter the position\n";
				cin >> num;
				StrInsert(S, num, V);
				break;
			case 12:
				cout << "Where do you want to start? How long do you want to delete?" << endl;
				cin >> pos >> num;
				StrDelete(S,pos,num);
				break;
			case 13:
				cout << "Which string do you want to see? The string T or the string S? They are represent the 1 and 0." << endl;
				cin >> num;
				if (num) {
					PrintAll(T);
				}
				else {
					PrintAll(S);
				}
				break;
		}
	}
	return 0;
}
/*
測試資料
2
xiang0
7
yuan0
14
0
*/