刚刚看到一道北大的OJ题,很简单的一道题。原题如下(偷个懒,直接截图):
看完这道题,我想大家都和我一样觉得这道题很简单,事实也是如此,毕竟通过率很高。
我先来说一下我的思路吧。我是想先把这些所有的字符串都得到,然后再去比较相邻的两个字符串相同后缀。
也就是第0个和第1个比较,第1个和第2个比较,第2个和第3个比较。。。。。如此反复比较了N-1次。
不过我们要求的是所有的字符串中的最长后缀,那么我们还差的一步就是比较得到这些字符中最短的一个,在这个程序中我是用一个参数在记录后缀的长度来实现最长的一个后缀。原因也很简单,因为既然是相同后缀,那么这个后缀一定是大家都有的,既然大家都有,那我随便用哪一个都不会有什么妨碍。那不妨就用第0个字符串来取得从第strlen(str[0])-minBackwards到第strlen(str[0])-1个就行了。如下是我的代码:
<span style="font-family:Courier New;font-size:18px;">#include <stdio.h> #include <string.h> #define MAXLENGTH 200 // 比较两个字符串的最长后缀 int compareSuffix(char a[], char b[]) { int len_a, len_b; len_a = strlen(a); len_b = strlen(b); int backwards = 0; int pa, pb; // 取两个字符串最短的为标准来从后向前遍历 for (pa = len_a-1, pb = len_b-1; (pa >= 0)&&(pb >= 0); --pa, --pb) { if(a[pa] == b[pb]) { ++backwards; } else break; } return backwards; } int main() { int n, i; while(scanf("%d", &n)!=0) { char str[MAXLENGTH][MAXLENGTH]; // 输入n个字符串 for(i = 0; i < n; ++i) { scanf("%s", str[i]); } int backwards = 0; int minBackwards = 300; // 依次比较两个字符串的相同后缀,找出最短的那个相同后缀 for (i = 0; i < n - 1; ++i) { backwards = compareSuffix(str[i], str[i+1]); if (backwards <= minBackwards) minBackwards = backwards; } if(minBackwards) { for (i = strlen(str[0])-minBackwards; i < strlen(str[0]); ++i) { printf("%c", str[0][i]); } } printf("\n"); } return 0; }</span><span style="font-family:SimSun;font-size:18px;"> </span>
现在分析可能是时间上出了问题,可是当我修改了代码之后发现还是同样的错误。于是,我再去看代码,感觉还是没有错的。上网查了一下,发现可能是我的while()循环出了问题,于是我就用上面的代码来测试了一下,果然不出所料。当我在第一次输入0的时候就出现了乱码,如果是前几次正常,那么后来输入0的时候,不会退出。
于是我就把while()循环中的语句修改了一下:
<span style="font-family:SimSun;font-size:18px;"> </span><span style="font-family:Courier New;font-size:18px;">while(1) { scanf("%d", &n); if(!n) break; ...................... }</span>
如果你看到了我这篇博客,并且知道这是为什么,可以给我评论留言。大家一起探讨一下。
原题连接:4073:最长公共字符串后缀(Longest String Postfix)