第四章 字符串与多重数组
此章作业将会将所学的BF算法和KMP算法敲出代码,进一步更新......
一. 既然涉及到字符串,先整理一下关于C++字符串的一些基础操作。(实际是自己忘了,想整理一下 )
输入:
(1)cin接受字符串时,遇“空格” “TAB” “回车”都结束。
例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; main () { char a[20]; cin>>a; cout<<a<<endl; } 输入:jkljkljkl 输出:jkljkljkl 输入:jkljkl jkljkl //遇空格结束,所以不能输入多个单词 输出:jkljkl
(2) cin.get(单个字符变量名),只能获取一个字符
例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; main () { char ch; ch=cin.get(); //或者cin.get(ch);只能获取一个字符 cout<<ch<<endl; } 输入:jljkljkl 输出:j
(3)cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格
例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; main () { char a[20]; cin.get(a,20); //有些类似getline。可以输入多个单词,中间空格隔开。 cout<<a<<endl; } 输入:jkl jkl jkl 输出:jkl jkl jkl 输入:abcdeabcdeabcdeabcdeabcde (输入25个字符) 输出:abcdeabcdeabcdeabcd (接收19个字符+1个'\0')
(4)cin.getline() // 接受一个字符串,可以接收空格并输出
例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; main () { char m[20]; cin.getline(m,5); //与上面基本相同。 cout<<m<<endl; } 输入:jkljkljkl 输出:jklj 接受5个字符到m中,其中最后一个为'\0',所以只看到4个字符输出; 如果把5改成20: 输入:jkljkljkl 输出:jkljkljkl 输入:jklf fjlsjf fjsdklf 输出:jklf fjlsjf fjsdklf //延伸: //cin.getline()实际上有三个参数,cin.getline(接受字符串到m,接受个数5,结束字符) //当第三个参数省略时,系统默认为'\0' 是‘/n’吧。 //如果将例子中cin.getline()改为cin.getline(m,5,'a');当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk
(5)getline() // 接受一个字符串,可以接收空格并输出,需包含“#include<string>”
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string> using namespace std; main () { string str; getline(cin,str); cout<<str<<endl; } 输入:jkljkljkl //VC6中有个bug,需要输入两次回车。 输出:jkljkljkl 输入:jkl jfksldfj jklsjfl 输出:jkl jfksldfj jklsjfl 和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数
(6)gets() // 接受一个字符串,可以接收空格并输出,需包含“#include<string>”
例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string> using namespace std; main () { char m[20]; gets(m); //不能写成m=gets(); cout<<m<<endl; } 输入:jkljkljkl 输出:jkljkljkl 输入:jkl jkl jkl 输出:jkl jkl jkl 类似cin.getline()里面的一个例子,gets()同样可以用在多维数组里面:
(7)getchar() //接受一个字符,需包含“#include<string>”
例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> using namespace std; main () { char ch; ch=getchar(); //不能写成getchar(ch); cout<<ch<<endl; } 输入:jkljkljkl 输出:j //getchar()是C语言的函数,C++也可以兼容,但是尽量不用或少用;
C输入:一些容易犯的错误,在我的另一个博客上面。地址:https://blog.csdn.net/SunPeishuai/article/details/83155638
建议:不熟的尽量不要用scanf输入字符或者字符串,容易出现bu
C++对于字符串的各种处理:https://blog.csdn.net/fyp19980304/article/details/80959067
二.字符串匹配
1.BF算法 伪代码:
1. 在串S和串T中设比较的起始下标i和j; 2. 循环直到S或T的所有字符均比较完; 2.1 如果S[i]==T[j],继续比较S和T的下一个字符; 2.2 否则,将i和j回溯(i=i-j+1,j=0),准备下一趟比较; 3. 如果T中所有字符均比较完,则匹配成功,返回匹配的起始比较下标(i-j);否则,匹配失败,返回-1
代码:
int BF(char S[ ], char T[ ]) { int i=0, j=0; while (i<S.Length&&j<T.length) { if (S[i]==T[j]) { i++; j++; } else { i=i-j+1; j=0; } } if (j>=T.length) return (i-j); else return -1; }
手敲BF验证代码:
#include<bits/stdc++.h> using namespace std; int BF(char T[], char S[]) { int i = 0, j = 0; while (i < strlen(T) && j < strlen(S)) { if (T[i] == S[j]) { i++; j++; } else { i = i - j + 1; j = 0; } } if (j == strlen(S)) return i - j; else return -1; } int main() { char T[] = { "ababcabcacbab" }; char S[] = { "abcac" }; cout << BF(T, S) << endl; return 0; }
输出结果为 5
KMP
推荐一篇博客:https://www.cnblogs.com/yjiyjige/p/3263858.html
伪代码:
1. 在串S和串T中分别设比较的起始下标i和j; 2. 循环直到S中所剩字符长度小于T的长度或T中所有字符均比较完毕 2.1 如果S[i]==T[j],继续比较S和T的下一个字符;否则 2.2 将j向右滑动到next[j]位置,即j=next[j]; 2.3 如果j=-1,则将i和j分别加1,准备下一趟比较; 3. 如果T中所有字符均比较完毕,则返回匹配的起始下标;否则返回-1;
void Compute_Next(char t[], int next[]) { int j=2,k; next[0]=-1;j=1; while(t[j]!='\0') { k=next[j-1]; while((k!=-1)&&(t[k]!=t[j-1])) k=next[k]; next[j]=++k; j++; } }
多维数组与矩阵压缩暂略