1、字符串的应用:单词计数
给定一段文本和关键词,统计关键词在该文本中出现的次数。
2、多维数组的应用:查找鞍点
若在矩阵A[n][m]中存在一个元素aij,该元素是第i行元素中最小值且又是第j列元素中最大值,则称此元素为该矩阵的一个鞍点。假设以二维数组存储矩阵A,设计算法求矩阵A的所有鞍点。
单词计数
点击查看代码
/*
* 基本思路:多次进行KMP算法匹配,匹配成功后计数++
* 我所理解的题目为:
* 在一段文章(没有空格或逗号、句号分隔)中统计某一单词的出现次数
*
* O(m+n)
*/
#include <cstring>
#include <iostream>
using namespace std;
void GetNext(int next[], char s[]) {
int j=0, k=-1;
next[0] = -1;
while(s[j+1] != ' ') {
if(k == -1 || s[j] == s[k]) {
++j, ++k;
if(s[j] == s[k])//小优化
next[j] = next[k];
else next[j] = k;
}
else k = next[k];
}
/*
for(int i=0; s[i]; ++i)
cout << next[i] << ' ';
cout << endl;
*/
return ;
}
int KMP(char s1[], char s2[]) {
int next[1001] = {0};
int count = 0, len1 = strlen(s1), len2 = strlen(s2);
GetNext(next, s2);
int i=0, j=0;
while(i < len1) {
if(j == -1 || s1[i] == s2[j])
++i, ++j;
else j = next[j];
if(j == len2) {//说明在s1中找到了s2
++count;
j = next[j-1];
}
}
return count;
}
int main()
{
ios::sync_with_stdio(false);
char s1[1001], s2[1001];
cout << "请输入文章:" << endl;
cin >> s1;
cout << "请输入要统计的单词:" << endl;
cin >> s2;
cout << KMP(s1, s2);
return 0;
}
查找鞍点
点击查看代码
/*
* 朴素算法:第一层循环为行,第二层循环为列找行中的最小值,第三层循环为行判断该最小值是否为该列的最大值,时间复杂度O(m*n^2),空间复杂度O(n*m)
* 优化思路:空间换时间。输入过程中存储每行最小值所在列编号,输入完成后只需要两层循环:第一层循环为行枚举每一行的最小值,第二层循环为行判断该最小值是否为所在列的最大值,复杂度O(n^2),空间复杂度O(n*(m+1))
* 假设矩阵中最大值为1e5
* 在输入的过程中记录每行的最小值的列号
* 输入完成后对每行的最小值判断其是否为所在列的最大值
* O(n*n)
*/
#include <cstring>
#include <iostream>
using namespace std;
const int M = 101;
const int N = 101;
int main()
{
ios::sync_with_stdio(false);
int n, m, a[N][M];
int minn[N] = {0};//存储每行最小值的列号
cout << "请输入矩阵大小:" << endl;
cin >> n >> m;
for(int i=0; i<n; ++i) {
cin >> a[i][0];
for(int j=1; j<m; ++j) {
cin >> a[i][j];
if(a[i][j] < a[i][minn[i]])
minn[i] = j;
}
}
bool flag;
for(int i=0; i<n; ++i) {
flag = false;
for(int j=0; j<n; ++j)
if(a[i][minn[i]] < a[j][minn[i]]) {
flag = true;
break;
}
if(!flag)
cout << "在第" << i+1 << "行" << "第" << minn[i]+1 << "列的数字" << a[i][minn[i]] << "是一个鞍点" << endl;
}
return 0;
}