此题虽然不难,但由于自己一开始对题目的理解出现问题,导致后来推倒重写。本题要点在于分别让两个字符串一个动另一个不动,输出此时的匹配长度。最后取2个匹配长度中最短的一个即可。我觉得此题我代码还是过长,有以下几个原因:子函数或许可以用for循环实现。最重要的一点:我一直以来的检测即毁灭的做法(即为了检查常常会改变数组元素作为标记)导致了一些不必要的数组及行为的出现。
#include<iostream>
#include<cstring>#include<algorithm>
using namespace std;
int isame(char *x, char *y) {//x短
for (int j = 0; j <= strlen(y) - strlen(x); j++) {
int sg = 1;//当前合法
for (int i = 0; x[i]; i++) {
if (x[i] + y[j + i] - 2 * '0' > 3) {
sg = 0; break;
}
}
if (sg) return 1;//合法
}
return 0;
}
int main() {
char s1[12], s2[12], s11[12], s22[12];
while (scanf("%s%s", s1,s2) != EOF) {//前短后长或前后等长
if (strlen(s1) > strlen(s2)) std::swap(s1, s2);
memcpy(s11, s1, sizeof(s1));
memcpy(s22, s2, sizeof(s2));
int lens1 = strlen(s1);//len1 is the shorter one
int lens2 = strlen(s2);
if (isame(s1, s2)) { printf("%d\n", lens1 > lens2 ? lens1 : lens2); continue; }
int len1 = 0,i,len2=0;//长上短下
for (i = 0; i < lens1-1; i++) {
s2[lens1 - i-1] = 0;
if (isame(s1 + i + 1, s2)) break;
}
len1 = i + 1 + lens2;
for (i = 0; i < lens1 - 1; i++) {//短上长下
s11[lens1 - i - 1] = 0;
if (isame(s11, s22 + lens2 - lens1 + i + 1)) break;
}
len2 = i + 1 + lens2;
int len = len1 < len2 ? len1 : len2;
printf("%d\n",len );
}
return 0;
}
以下是网上的代码,我认为写的很好,抓住了问题的关键:重合部分的长度。非常巧妙。
- #include<stdio.h>
- #include<string.h>
- char h1[110],h2[110];
- int main()
- {
- while(scanf("%s%s",h1,h2)!=EOF)
- {
- int i,j,t,m,n;
- int temp,conut1,conut2;
- i=j=t=0;
- m=strlen(h1);
- n=strlen(h2);
- while(j<m&&i<n)
- {
- if(h1[j]+h2[i]-96<=3)
- {
- i++,j++;
- }
- else
- t++,i=0,j=t;
- }
- conut1=m+n-i;
- i=j=t=0;
- while(j<n&&i<m)
- {
- if(h2[j]+h1[i]-96<=3)
- {
- i++,j++;
- }
- else
- t++,i=0,j=t;
- }
- conut2=m+n-i;
- printf("%d\n",conut1 < conut2 ? conut1 : conut2 );
- }
- return 0;
- }
以下这个代码更短且更巧妙,但现在看不太明白...
#include<cstdio>
#include<cstring>
const int maxn = 100;
char a[maxn + 1], b[maxn + 1];
int n1, n2;
int min(const int &i, const int &j) {
return i<j ? i : j;
}
int minLen(char *s1, char *s2, int &n) {// n为s1的长度
int sumLen = n1 + n2, minn = min(n1, n2), len = sumLen;
for (int i = 0; i<n; i++) {
int ok = 1, fix = min(n - i, minn);//fix的计算是一个难点
for (int j = 0; j<fix; j++)
if (s1[i + j] == '2'&&s2[j] == '2') {
ok = 0; break;
}
if (ok&&len>sumLen - fix)len = sumLen - fix;
}
return len;
}
int main() {
while (scanf("%s%s", &a, &b) == 2) {
n1 = strlen(a), n2 = strlen(b);//无意中用到了逗号运算符
minLen(a, b, n1);
minLen(b, a, n2);
printf("%d\n", min(minLen(a, b, n1), minLen(b, a, n2)));//用min函数取两次结果的最小值
}
}