【中级】密码截取
题目
Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?题目出处
思路
把字符串依次截断,倒序前半部分。
若为ABBA型,则比较倒序后的字符串与截断后的字符串有几位相同。
若为ABA型,跳过截断后第一个字符然后比较。
选出最大值。
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * flashback(char* a,int p) //倒序函数,返回倒序后的数组的指针
{
int i;
char *c;
c = (char*)malloc((p+1) * sizeof(char)); //编译器不支持变长数组,所以动态分布内存
for (i = 0; i <= p; i++) //牢记用了malloc后一定要free,否则可能造成内存泄漏
c[i] = a[p - i];
return c;
}
int main(void)
{
char a[10000];
int i, j,max,k,end,count;
char* b; //用来指向倒序后的数组
while (gets(a) != NULL)
{
for (i = 0, max = 0; i < strlen(a) - 2; i++) //只用循环到倒数第2个字符
{
b=flashback(a, i);
end = (i < (strlen(a) - i - 1)) ? i : (strlen(a) - i - 1); //最多比较的长度为较短的数字组长度
for (j = 0, k = i + 1, count=0; j <= end; k++, j++) //abba型
if (a[k] == b[j])
count++;
else break;
max = (max > (count*2)) ? max : (count*2);
for (j = 0, k = i + 2, count = 0; j <= end; k++, j++) //aba型
if (a[k] == b[j])
count++;
else break;
max = (max > (count * 2+1)) ? max : (count * 2+1); //更新最大值
free(b); //释放动态内存
}
printf("%d\n", max);
}
return 0;
}
反思
原理不复杂,分开判定即可,代码可以优化,通过判断将aba型和abba型,修改k值,通过一个遍历得到答案。
一定要注意使用free,以免内存泄漏。