1. 程式人生 > >資料結構串的應用,實驗

資料結構串的應用,實驗

#include<iostream>
#include<string.h>
using namespace std;
const int MAXNUM = 1000;
int main() {
	int t;
	cin >> t;
	char chars[MAXNUM];
	char chart[MAXNUM];
	while (t--) {
		memset(chars, 0, MAXNUM);
		memset(chart, 0, MAXNUM);
		char m;
		int n = 1;
		while (cin >> m) {
			chars[n] = m;
			n++;
		}
		int nums = n;
		n = 1;
		while (cin >> m) {
			chart[n] = m;
			n++;
		}
		int numt = n;


		
	}
}

哇太氣人了,寫到這裡發現這道題要求用字串,這真的難受

#include<iostream>
#include<string>
using namespace std;
class myString {
private:
	string mainstr;
	int size;
	void GetNext(string p, int next[]);
	int kmpFind(string p, int pos, int next[]);

public:
	myString();
	~myString();
	void SetVal(string sp);
	int kmpFindSubstr(string p, int pos);
 };

myString::myString() {
	size = 0;
	mainstr = "";
}
myString::~myString() {
	size = 0;
	mainstr = "";
}

void myString::SetVal(string sp) {
	mainstr = "";
	mainstr.assign(sp);//這什麼
	size = mainstr.length();
}

int myString::kmpFindSubstr(string p, int pos) {
	int i;
	int L = p.length;
	int *next = new int[L];
	GetNext(p, next);
	for (int i = 0; i < L; i++) {
		cout << next[i];
	}
	cout << endl;
	int v = -1;
	v = kmpFind(p, pos, next);
	delete[] next;
	return v;
}

void myString::GetNext(string p, int next[]) {

}

int  myString::kmpFind(string p, int pos, int next[]) {

}

寫到這裡突然想,為什麼非要用類來實現呢

 

自己應該學習一些大佬的程式碼風格,力求簡潔明瞭快速

#include<iostream>
#include<string>
#include<string.h>
const int MAXN = 1000;
using namespace std;

void getNext(string p, string next);
int kmpFind(string p, string s, string next, int pos);


void getNext(string p, string next) {
	int i = 1;
	next[i] = 0;
	int j = 0;
	while (i < p[0]) {
		if (j == 0 || p[i] == p[j]) {
			i++;
			j++;
			next[i] = j;
		}
		else j = next[j];
	}
}

int  kmpFind(string s, string p, string next,int pos ) {
	int i = pos;
	int j = 1;
	while (i <= s[0] && j <= p[0]) {
		if (j == 0 || s[i] == p[j]) {
			i++;
			j++;
		}
		else 
			j = next[j];
	}
	if (j > p[0]) return i - p[0];
	else return 0;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		string s1, p1, s, p, next1, next;
		cin >> s1 >> p1;
		s = "a" + s1;
		p = "a" + p1;
		getNext(s, next1);
		next = "a" + next1;
		int nums = s.length();
		int key=0;
		for (int m = 1; m <= nums; m++) {
			key=kmpFind(s, p, next, m);
			if (key != 0)
				break;
		}
		cout << key << endl;
	}
	return 0;
}

自己生搬硬套,出錯很自然,但是現在無心搞這個啊,要是課前預習好,並且上課沒有犯困就好了。先回去處理其他作業吧

 

 

string 定義後需要初始化。

 

 

#include<iostream>
#include<string>
#include<string.h>
const int MAXN = 1000;
using namespace std;

void cal_next(string str, int *next, int len);
int KMP(string str, int slen, string ptr, int plen);

void cal_next(string str, int *next, int len)
{
	next[0] = -1;//next[0]初始化為-1,-1表示不存在相同的最大字首和最大字尾
	int k = -1;//k初始化為-1
	for (int q = 1; q <= len - 1; q++)
	{
		while (k > -1 && str[k + 1] != str[q])//如果下一個不同,那麼k就變成next[k],注意next[k]是小於k的,無論k取任何值。
		{
			k = next[k];//往前回溯
		}
		if (str[k + 1] == str[q])//如果相同,k++
		{
			k = k + 1;
		}
		next[q] = k;//這個是把算的k的值(就是相同的最大字首和最大字尾長)賦給next[q]
	}
}

int KMP(string str, int slen, string ptr, int plen)
{
	int *next = new int[plen];
	cal_next(ptr, next, plen);//計算next陣列
	for (int j = 0; j < sizeof(next); j++) {
		cout << next[j] << " ";
	}
	cout << endl;
	int k = -1;
	for (int i = 0; i < slen; i++)
	{
		while (k >-1 && ptr[k + 1] != str[i])//ptr和str不匹配,且k>-1(表示ptr和str有部分匹配)
			k = next[k];//往前回溯
		if (ptr[k + 1] == str[i])
			k = k + 1;
		if (k == plen - 1)//說明k移動到ptr的最末端
		{
			//cout << "在位置" << i-plen+1<< endl;
			//k = -1;//重新初始化,尋找下一個
			//i = i - plen + 1;//i定位到該位置,外層for迴圈i++可以繼續找下一個(這裡預設存在兩個匹配字串可以部分重疊),感謝評論中同學指出錯誤。
			return i - plen + 2;//返回相應的位置
		}
	}
	return 0;
}
int main() {
	int t;
	cin >> t;
	while (t--) {
		string s, p;
		cin >> s >> p;
		int key = KMP(s, s.length(), p, p.length());
		cout << key << endl;
	}
	return 0;
}

借鑑了網上的,但是這個的思想和課本上的不大一樣

https://blog.csdn.net/starstar1992/article/details/54913261/

#include<iostream>
#include<string>
#include<string.h>
const int MAXN = 1000;
using namespace std;

void getNext(string p, int*next);
int KMP(string s, string p, int*next);
void getNext(string p, int*next) {
	int j = 0;
	next[0] = -1;
	int k = -1;
	while (j < p.length()) {
		if (k == -1 || p[j] == p[k]) {
			j++;
			k++;
			next[j] = k;
		}
		else {
			k = next[k];
		}
	}
}
int KMP(string s, string p, int*next) {
	int i = 0, j = 0;
	int nums = s.length();
	int nump = p.length();
	while (i < nums && j < nump) {
		if (j == -1 || s[i] == p[j]) {
			i++;
			j++;
			cout << i << " " << j << endl;
		}
		else {
			j = next[i];
		}
		
	}
	if (j > p.length())
		return (i - p.length() + 1);
	else
		return 0;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		string s, p;
		cin >> s >> p;
		int *next = new int[p.length()];
		getNext(p, next);
		for (int i = 0; i < p.length(); i++) {
			cout << next[i] << " ";
		}
		cout << endl;
		int key = KMP(s, p, next);
		cout << key << endl;
	}
	return 0;
}

 

 

 

改了,並且第一次提交runtime,後來

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

void getNext(string p, int*next);
int KMP(string s, string p, int*next);
void getNext(string p, int*next) {
	int j = 0;
	next[0] = -1;
	int k = -1;
	while (j < p.length()-1) {
		if (k == -1 || p[j] == p[k]) {
			j++;
			k++;
			next[j] = k;
		}
		else {
			k = next[k];
		}
	}
}
int KMP(string s, string p, int*next) {
	int i = 0, j = 0;
	int slen,plen;
	slen = s.length();
	plen = p.length();
	while (i < slen&&j<plen){
		if (j == -1 || s[i] == p[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
		
	}
	if (j ==plen)
		return (i -j + 1);
	else
		return 0;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		string s, p;
		cin >> s >> p;
		int *next = new int[p.length()];
		getNext(p, next);
		for (int i = 0; i < p.length(); i++) {
			cout << next[i] << " ";
		}
		cout << endl;
		int key = KMP(s, p, next);
		cout << key << endl;
		delete[] next;
	}
	return 0;
}

把getNExt 函式中

#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;

void getNext(string p, int*next);
int KMP(string s, string p, int*next);
void getNext(string p, int*next) {
	int j = 0;
	next[0] = -1;
	int k = -1;
	while (j < p.length()-1) {
		if (k == -1 || p[j] == p[k]) {
			j++;
			k++;
			next[j] = k;
		}
		else {
			k = next[k];
		}
	}
}
int KMP(string s, string p, int*next) {
	int i = 0, j = 0;
	int slen,plen;
	slen = s.length();
	plen = p.length();
	while (i < slen&&j<plen){
		if (j == -1 || s[i] == p[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
		
	}
	if (j ==plen)
		return (i -j + 1);
	else
		return 0;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		string s, p, h;
		cin >> s >> p >> h;
		int *next = new int[p.length()];
		getNext(p, next);
		int key = KMP(s, p, next);
		cout << s << endl;

		if (key != 0) {
			if (p.length() == h.length()) {
				for (int i = key - 1; i < key-1 + h.length(); i++) {
					s[i] = h[i - key + 1];
				}//string 會預設初始化為" ",訪問定義以外的空間,也是" " 
			}
			else {
				int numba = p.length() < h.length() ? p.length() : h.length();
				for (int i = key - 1; i < key-1 + numba; i++) {
					s[i] = h[i - key + 1];
				}
				if (numba == p.length()) {
					s.insert(key + numba - 1, h, numba, h.length() - 1);
				}
				else {
					s.insert(key + numba - 1, p, numba, p.length() - 1);
				}
			}
			cout << s << endl;
		}
		else {
			cout << s << endl;
		}
		delete[] next;
	}
	return 0;
}

的 while() 判斷條件改成 j<p.length()-1 ,提交成功

 

 

#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;

void getNext(string p, int*next);
int KMP(string s, string p, int*next);
string matched_Prefix_Postfix(string str);
void getNext(string p, int*next) {
	int j = 0;
	next[0] = -1;
	int k = -1;
	while (j < p.length()-1) {
		if (k == -1 || p[j] == p[k]) {
			j++;
			k++;
			next[j] = k;
		}
		else {
			k = next[k];
		}
	}
}
int KMP(string s, string p, int*next) {
	int i = 0, j = 0;
	int slen,plen;
	slen = s.length();
	plen = p.length();
	while (i < slen&&j<plen){
		if (j == -1 || s[i] == p[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
		
	}
	if (j ==plen)
		return (i -j + 1);
	else
		return 0;
}
string matched_Prefix_Postfix(string str) {
	string front;
	int prs=0;
	for (int i = 1; i < str.length(); i++) {
		string back = str.substr(i, str.length() - i);
		int* next = new int[back.length()];
		getNext(back, next);
		int key = KMP(str, back, next);
		if (key == 1) {
			front = back;
			prs = i;
			break;
		}
	}
	if (prs != 0)
		return front;
	else
		return "empty";

}

int main() {
	int t;
	cin >> t;
	while (t--) {
		string s;
		cin >> s;
		string ans=matched_Prefix_Postfix(s);
		cout << ans << endl;
	}
	return 0;
}

string 的   t=b, 如果t比b大,那麼是整個變成了b,還是一部分變成了 b,剩下的還是原來的元素?

 

 

#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;

void getNext(string p, int*next);
int KMP(string s, string p, int*next);
int findLong(string str);
void getNext(string p, int*next) {
	int j = 0;
	next[0] = -1;
	int k = -1;
	while (j < p.length()-1) {
		if (k == -1 || p[j] == p[k]) {
			j++;
			k++;
			next[j] = k;
		}
		else {
			k = next[k];
		}
	}
}
int KMP(string s, string p, int*next) {
	int i = 0, j = 0;
	int slen,plen;
	slen = s.length();
	plen = p.length();
	while (i < slen&&j<plen){
		if (j == -1 || s[i] == p[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
		
	}
	if (j ==plen)
		return (i -j + 1);
	else
		return 0;
}

int findLong(string str) {
	int num=-1;
	for (int i = 0; i < str.length()-1; i++) {
		for (int j = 1; j <= (str.length()-i)/2; j++) {
			string p = str.substr(i, j);
			int np = p.length();
			int *next = new int[np];
			getNext(p, next);
			int key = KMP(str, p, next);
			if (key != 0) {
					key = 0;
					string ptr = str.substr(i + j, str.length() - j);
					key = KMP(ptr, p, next);
					if (key != 0&& np>num) {//這裡特別奇怪,如果用 p.length()就一直判斷錯誤
						num = p.length();
					}
				}
			delete[] next;
		}
	}
	return num;
}
int main() {
	int t;
	cin >> t;
	while (t--) {
		string s;
		cin >> s;
		int ans=findLong(s);
		cout << ans << endl;
	}
	return 0;
}
#include<iostream>
#include<string>
using namespace std;
int main() {
	string s;
	while (getline(cin,s)) {
		s[0] = s[0] - 32;
		for (int i = 1; i < s.length(); i++) {
			if (s[i] == ' ') {
				s[i + 1] = s[i + 1] - 32;
			}
		}
		cout << s << endl;
	}
	return 0;
}

cin 遇到空格和回車就會停止,輸入含空格字串用 getline(cin,s);