資料結構串的應用,實驗
阿新 • • 發佈:2018-11-08
#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);