公共子串计算
计算两个字符串的最大公共字串的长度,字符不区分大小写
最长公共子串和最长公共子序列
例:str1=“123ABCD456” str2 = “ABE12345D”
最长公共子串是:123
最长公共子序列是:12345
这两个都可以用动态规划,只是状态转移方程有点区别
最长公共子序列是:
dp[i][j] – 表示子串str1[0…i]和子串str[0…j]的最长公共子序列
当str1[i] == str2[j]时,dp[i][j] = dp[i-1][j-1] + 1;
否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
最优解为dp[len1-1][len2-1];
最长公共子串是: dp[i][j] – 表示以str1[i]和str2[j]为结尾的最长公共子串 当str1[i] == str2[j]时,dp[i][j] = dp[i-1][j-1] + 1; 否则,dp[i][j] = 0;
最优解为max(dp[i][j]),其中0<=i<len1, 0<=j<len2;
法一:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str1[100];
char str2[100];
while((scanf("%s %s",&str1,&str2))!=EOF)
{
int max =0;
for(int i=0;i<strlen(str1);i++)
{
for(int j=0;j<strlen(str2);j++)
{
int m =0;
int n =0;
while(str1[m+i]!='\0' && str2[n+j]!='\0' && toupper(str1[m+i])==toupper(str2[n+j]))
{
n++;
m++;
if(n > max)
max =n;
}
}
}
printf("%d\n",max);
}
return 0;
}
法二:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string transform_s(string str)
{
for(int i = 0; i<str.size(); i++)
{
if (str[i]>= 'A' && str[i] <= 'Z')
str[i] += 32;
}
return str;
}
int main()
{
string str1, str2;
while(cin >> str1 >> str2)
{
// str1 = transform_s(str1);
// str2 = transform_s(str2);
int max = 0;
int l1 = str1.size();
int l2 = str2.size();
vector<vector<int>> dp(l1 + 1, vector<int>(l2 + 1, 0));
for(int i = 1; i <= l1; i++)
{
for(int j = 1; j <= l2; j++)
{
if(str1[i-1] == str2[j-1 {
dp[i][j] = dp[i-1][j-1] +1;
if(dp[i][j] > max)
max = dp[i][j];
}
}
}
cout << max << endl;
}
return 0;
}
尼科彻斯定理
验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
例如:
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
数学公式直接可以推出来首项是m*m+1-m,有m项
#include<stdio.h>
#include<iostream>
using namespace std;
//数学公式直接可以推出来首项是m*m+1-m,有m项
int main(){
int m;
while(cin>>m){
int s = m*m+1-m;
cout<<s;
for(int i=1;i<m; i++)
cout<<'+'<<s+2*i;
cout<<endl;
}
return 0;
}
一二维数组操作
输入数据按下列顺序输入:
1 表格的行列值
2 要交换的两个单元格的行列值
3 输入要插入的行的数值
4 输入要插入的列的数值
5 输入要获取运动轨迹的单元格的值
// An highlighted block
#include <iostream>
using namespace std;
int main() {
int r, c, r1, c1, r2, c2, ri, ci, rt, ct;
while (cin >> r >> c >> r1 >> c1 >> r2 >> c2 >> ri >> ci >> rt >> ct)
{
if (r>9 || c>9)
cout << "-1" << endl;
else
cout << "0" << endl;
if (r1 >= 0 && r1<r && c1 >= 0 && c1<c && r2 >= 0 && r2<r && c2 >= 0 && c2<c)
cout << "0" << endl;
else
cout << "-1" << endl;
if (ri >= 0 && ri<r && r<9)
cout << "0" << endl;
else
cout << "-1" << endl;
if (ci >= 0 && ci<c && c<9)
cout << "0" << endl;
else
cout << "-1" << endl;
if (rt >= 0 && rt<r && ct >= 0 && ct<c)
cout << "0" << endl;
else
cout << "-1" << endl;
}
return 0;
}
统计大写字母个数
找出给定字符串中大写字符(即’A’-‘Z’)的个数
#include<stdio.h>
#include<string.h>
int main()
{
char a[65536];
int i,k;
while(scanf("%s",a)!=EOF)
{
k=0;
for(i=0;i<strlen(a);i++)
{
if(a[i]<=90 && a[i]>=65)
{
k=k+1;
}
}
printf("%d\n",k);
}
return 0;
}
字符串运用-密码截取
Catcher 是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?
(注意:记得加上while处理多个测试用例)
// An highlighted block
#include<iostream>
#include<vector>
#include<string>
#include<cmath>
using namespace std;
//最长回文子串
int getlen(int l,int r,string s){
while(l>=0 && r<s.size() && s[l]==s[r]){
l--;
r++;
}
return r-l-1;
}
int main(){
string s;
while(cin>>s){
int cur=0;
for(int i=0;i<s.size();i++){
cur=max(max(getlen(i,i,s),getlen(i,i+1,s)),cur);
}
cout<<cur<<endl;
}
return 0;
}
一求连续最大的bit数
功能: 求一个byte数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1
#include <iostream>
using namespace std;
int main(){
int n;
while(cin >> n){
int k=0;
while(n){//遇到进制的问题,多考虑用位运算
n=n&(n<<1);
k++;
//求n与n移位后按位与的结果,如果连续的1的个数为1,则更新后的n为0;
}//如果有多个连续的1,则按位与之后其他位都为0,而连续1的个数减1;依次循环,直到n为0,k记录了移位多少次,即为连续1的个数
cout << k <<endl;
}
return 0;
}