BAT某公司招聘在线编程题目的两种解法

    日前参加了某知名互联网公司的实习生招聘,做到了在线编程题,题目大意是这样的,实现一个源编码的解压或则压缩工作,编码的完整格式为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);
}

测试结果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值