#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.youkuaiyun.com/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);