#每日一题#腾讯笔试题

10 篇文章 0 订阅
9 篇文章 1 订阅

     在一组数的编码中,若任意两个相邻的代码只有一个二进制数不同,则称这种编码为格雷码(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值