//求一个字符串中连续出现次数最多的子串。
#include <cstdlib> #include <vector> #include <iostream> #include <string> using namespace std; pair<int, string> fun(conststring& str) { vector<string> substrs; int maxcount = 1; int count = 1; string substr; int len = str.length(); for(int i = 0; i< len; i++) substrs.push_back(str.substr(i, len-i)); for(int i = 0; i< len; i++) { for(int j= i+1; j < len; j++) { count = 1; if(substrs[i].substr(0, j-i) ==substrs[j].substr(0, j-i)) { ++count; for(int k = j+(j-i); k < len; k+= j-i) { if(substrs[i].substr(0, j-i)== substrs[k].substr(0, j-i)) count++; else break; } if(count > maxcount) { maxcount =count; substr =substrs[i].substr(0, j-i); } } } } return make_pair(maxcount,substr); } int main(int argc, char *argv[]) { string str; pair<int,string> rs; while(cin>> str) { rs = fun(str); cout << rs.second<< ":"<< rs.first<< "\n"; } system("PAUSE"); returnEXIT_SUCCESS; }
//编程之美2.12快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值。首先对数组进行排序,然后遍历一次。时间复杂度O(n)。
#include <cstdlib> #include <iostream> #include <string> #include <algorithm> using namespace std; bool cmp(int a, int b) { returna < b; } void find(int a[], int sum) { int i,j; for(j= 6, i = 0; i < j;) { if(a[i] + a[j]< sum) i++; else if(a[i] + a[j]> sum) j--; else { cout << i<< " "<< j <<endl; i++; j--; } } return; } int main(int argc, char *argv[]) { int a[] = {5, 6, 1, 4,7, 9, 8}; int sum = 10; sort(a, a+7, cmp); for(int i = 0; i< 7; i++) cout << a[i]<< " "; cout<< endl; find(a, sum); system("PAUSE"); returnEXIT_SUCCESS; }
//编程之美3.3 计算字符串的相似度。
#include <cstdlib> #include <iostream> #include <string> #include <algorithm> using namespace std; int min(int t1, int t2, int t3) { if(t1 >t2) t1 = t2; if(t1 >t3) t1 = t3; return t1; } int calculate(string strA, int Abegin, int Aend, string strB,int Bbegin, int Bend) { if(Abegin> Aend) { if(Bbegin > Bend) return0; else returnBend-Bbegin+1; } if(Bbegin> Bend) { if(Abegin > Aend) return0; else returnAend-Abegin+1; } if(strA[Abegin] ==strB[Bbegin]) return calculate(strA, Abegin+1, Aend, strB,Bbegin+1, Bend); else { int t1 = calculate(strA, Abegin, Aend, strB,Bbegin+1, Bend); int t2 = calculate(strA, Abegin+1, Aend, strB,Bbegin, Bend); int t3 = calculate(strA, Abegin+1, Aend, strB,Bbegin+1, Bend); return min(t1, t2, t3)+1; } } int main(int argc, char *argv[]) { string strA ="xabcdae"; string strB ="xfdfa"; int m = calculate(strA,0, 7, strB, 0, 5); cout<< m <<endl; system("PAUSE"); returnEXIT_SUCCESS; }
使用以上算法存在的问题:在递归的过程中,有数据被重复计算。使用DP,类似于求两个字符串的最长公共子序列。
#include <cstdlib> #include <iostream> #include <string> #include <algorithm> using namespace std; int min(int t1, int t2, int t3) { if(t1 >t2) t1 = t2; if(t1 >t3) t1 = t3; return t1; } int calculate(string strA, string strB) { int lenA =strA.length()+1; int lenB =strB.length()+1; int c[100][100]; for(int i = 1; i< lenA; i++) c[i][0] =i; for(int j = 1; j< lenB; j++) c[0][j] =j; c[0][0] = 0; for(int i = 1; i< lenA; i++) for(int j= 1; j < lenB; j++) { if(strB[j-1] == strA[i-1]) c[i][j] = c[i-1][j-1]; else c[i][j] =min(c[i][j-1], c[i-1][j], c[i-1][j-1])+1; } for(int i = 0; i< lenA; i++) { for(int j= 0; j < lenB; j++) cout << c[i][j]<< " "; cout<< endl; } returnc[lenA-1][lenB-1]; } int main(int argc, char *argv[]) { string strB ="xabcdae"; string strA ="xfdfa"; int m = calculate(strA,strB); cout<< m <<endl; system("PAUSE"); returnEXIT_SUCCESS; }