日前参加了某知名互联网公司的实习生招聘,做到了在线编程题,题目大意是这样的,实现一个源编码的解压或则压缩工作,编码的完整格式为24位01代码,每六位之间用“:”间隔,如“000111:111111:111101:000000”,对于该编码实现压缩后为“111:111111:111101:”,对于编码“::11:1”, 解压后的结果为“000000:000000:000011:000001”,需要写一个程序来完成编码的压缩和解压工作。
输入:第一行为一个整数,0或1,输入1表示完成解压工作,输入0表示完成压缩工作;
第二行输入一个编码。
输出:解压或则压缩后对应的编码。
在刚看这个题目的时候,觉得题目并不复杂,应该很容易写出代码,但由于是在考试,右上角还在计时,因此在想思路的时候也就想着是完成题目的要求,而没有过多的考虑代码的效率等。当动手写程序的时候,感觉其中涉及到数组的边界问题还需要仔细的计算,逻辑也有一点复杂。我当时在线编程的时候,在实现解压部分功能的时候,代码就写的比较臃肿了,因为当时一时没有想好简洁的方式,就采用了如下算法一的做法:
算法一:
int main()
{
int sign=0,len[4]={0,0,0,0},i=0,j = 0,space=0;
char s[28], d[28];
scanf("%d",&sign);
scanf("%s",s);
if(sign) //jieya
{
space =0;
for(i = 0; s[i] != '\0'; i++)
{
if(s[i] != ':')
{
len[space]=len[space]+1;
}
else
{
space++;
}
}
for(i = 0; i < 27; i++)
{
d[i]='0';
if((i+1)%7==0)
d[i] = ':';
}
for(j=0;j<len[0];j++)
{
d[6-len[0]+j]=s[j];
}
for(j=0;j<len[1];j++)
{
d[13-len[1]+j]=s[j+1+len[0]];
}
for(j=0;j<len[2];j++)
{
d[20-len[2]+j]=s[j+2+len[0]+len[1]];
}
for(j=0;j<len[3];j++)
{
d[27-len[3]+j]=s[j+3+len[0]+len[1]+len[2]];
}
d[27]='\0';
}
else //yasuo
{
space =0;
j=0;
for(i=0; s[i]!='\0';i++)
{
if(space==0)
{
if(s[i]=='0')
continue;
else
{
d[j++]=s[i];
space=1;
}
}
else
{
d[j++]=s[i];
}
if(s[i]==':')
space=0;
}
d[j]='\0';
}
printf("%s\n",d);
}
算法一的思路在实现解压时,采用一个数组d来存储最终结果,首先对数组数据部分初始化为全0,然后遍历一次源数组s,得到每一部分1的长度,然后对应写到目的数组d中,在对数组d写入1的过程,我是分别用了四个循环,最开始我想通过一个循环,就完成所有的写入1的工作,由于当时考虑到那样又得多一些逻辑的思考,为了节约时间,就选择了简单的写法,虽然代码臃肿一些,但是能够达到效果。在实现压缩时,基本思路为:设置一个标志位,对处于最前面的0,全部忽略,当遇到一个1后,就更改标注为,此后遇到的0都需要记录,直到遇到“:”,又重新开始上述这个过程。这部分的代码写的倒是比较简洁。
后来考完试后,我就重新想了一下解压的工作,觉得倒着思考写入1的过程比较好,依次设置两个指针i和j,分别指向源数组s和目的数组d的最后一个元素,如果i和j指向同一个区域(四段编码的同一段),并且i指向的为1,就写入j指向的位置,两个指针分别前移一位。这样写出的代码,只需要一个循环,就可以完成所有工作,效率也要高一点,就是下面的算法二:
算法二:
#include<stdio.h>
#include <string.h>
int main()
{
int sign=0,i=0,j = 0,space_d = 0, space_s = 0;
char s[28], d[28];
scanf("%d",&sign);
scanf("%s",s);
if(sign) //jieya
{
space_d = 4;
space_s = 4;
j = strlen(s)-1;
for(i = 26 ; i >= 0; --i)
{
if(s[j] == ':')
{
space_s--;
j--;
}
if ((i + 1) % 7 == 0)
{
d[i] = ':';
space_d--;
}
else
{
if (space_d == space_s && j >= 0)
d[i] = s[j--];
else
d[i] = '0';
}
}
d[27]='\0';
}
else //yasuo
{
space_d =0;
j=0;
for(i=0; s[i]!='\0';i++)
{
if(space_d==0)
{
if(s[i]=='0')
continue;
else
{
d[j++]=s[i];
space_d=1;
}
}
else
{
d[j++]=s[i];
}
if(s[i]==':')
space_d=0;
}
d[j]='\0';
}
printf("%s\n",d);
}
测试结果: