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] != '\0') {
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;
}