#每日一题#腾讯笔试题

来源:互联网 发布:浙江淘宝网络有限公司 编辑:程序博客网 时间:2024/05/24 07:06

     在一组数的编码中,若任意两个相邻的代码只有一个二进制数不同,则称这种编码为格雷码(Gary Code),请编写一个函数,使用递归的方法生成N位的格雷码。给定一个整数n,请返回n位的格雷码,顺序为从0开始。

   测试样例:

     输入:1

    返回:“0”,“1”。

    (1)首先给出二进制--->格雷码的转换:
      此方法从对应的n位二进制字中直接得到n位格雷码字,步骤如下:
          (1)对n位二进制的码字,从右向左,以0到n- 1编号

          (2)如果二进制码字的第 i 位和第i + 1位相同,则对应的格雷码第 i 位为0,否则为1(当i + 1 = n时,二进制码的第n位被认为是0,即第n - 1位不变)

    例如:

 二进制码0101,为4位数,所以其所转化为格雷也必为4位数,因此可取转成之二进制位码第五位为0,即0 b3 b2 b1 b0。

 



 根据上面的方法可得出0101对应的格雷码为0111。

  (2)格雷码--->二进制码(解码)

      从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。依次异或,直到最低位。依次异或转换后的值(二进制数)就是格雷码转换后的二进制码的值。


    例如:格雷码1010

      (a)最左边的1不变,则二进制位 1 b2 b1 b0

      (b)b2 = 1 异或 0 = 1,则二进制为 1 1 b1 b0

      (c)b1 = 1 异或 1 =  0,则二进制为 1 1 0 b0

      (d)b0 = 0 异或 0 = 1,则二进制为 1 1 0 0

   下面给出我自己编写的转换程序:


#include <stdio.h>#include <stdlib.h>#include <string.h>#define N 100//获取整数的二进制码void getbinary(int x,char *s){    if(x == 0){        *s = 0 + '0';        return;    }    if(x){        *s = x % 2 + 48;        x = x / 2;        getbinary(x,s + 1);    }    }//获取整数的格雷码////        B = 0  b3  b2  b1  b0//            \  / \ / \ / \ ///              G =  g3   g2  g1  g0////void getgray_code(int x){    int n = x >> 1;    int len1,len2,i;    char s1[N] = {0};    char s2[N] = {0};    getbinary(x,s1);    getbinary(n,s2);        len1 = strlen(s1);        len2 = strlen(s2);        for(i = len2 - 1;i >= 0;i--){            s1[i] = ((s1[i] - '0') ^ (s2[i] - '0')) + 48;                    }        for(i = len1 - 1;i >= 0;i--){            printf("%c ",s1[i]);        }        printf("\n");   }int main(int argc,char **argv){    int n;    int len;    int i ;    char s[N] = {0};    while(1){        printf("请输入一个整数n:(-1 代表退出)\n");        scanf("%d",&n);        if(n == -1){            printf("error!\n");            exit(1);        }        #if 1        printf("binary code:\n");        getbinary(n,s);        len = strlen(s);        for(i = len - 1;i >= 0;i--){            printf("%c ",s[i]);        }        printf("\n");        #endif        printf("gray code:\n");        getgray_code(n);    }    return 0;}

我们先来看执行的结果:

 该程序将二进制码和格雷码都进行了打印,在程序中用到字符数组来进行存储。。。



  下面给出另一种解法:该思路就是整数n的格雷码等于整数n - 1的格雷码前一部分加“0”,后一部分加上“1”.

 具体的代码如下:

 

#include <iostream>#include <string>#include <stdlib.h>using namespace std;//格雷码string * getgray(int n){    int count = 1 << n;    int len;    string *strArr = new string[count];    if(n == 0){        cout<<"格雷码转换n值大于0!!!"<<endl;        exit(1);    }    if(n == 1){        strArr[0] = "0";        strArr[1] = "1";        return strArr;    }else{        string *strArr1 = getgray(n - 1);        len = count / 2;        for(int i = 0;i< len;i++){            strArr[i] = "0" + strArr1[i];        }        for(int i = 0;i < len;i++){            strArr[count - i - 1] = "1" + strArr1[i];        }        return strArr;    }}int main(int argc,char**argv){    int n;    int len;    int i;    string *b;    while(1){        cout<<"请输入整数n:(-1 == quit)"<<endl;        cin>>n;        if(n == -1){            cout<<"error!"<<endl;            exit(1);        }        len = 1 << n;                b = getgray(n);        #if 0        for(int i = 0;i < len;i++){            cout<<b[i]<<endl;        }        #endif        cout<<b[n]<<endl;        b = NULL;   }}

其执行结果如下:

 

   这里使用到了C++中的string类,还要说明一下string对象进行加法时,比如:“0” + “1” = “01”,只是字符的连接,这一点比较重要!!!个人还是觉得第二种方法比较好。。。

0 0
原创粉丝点击