//求一个字符串中连续出现次数最多的子串。
#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;
}