格雷码生成算法详解(c语言)

Gray Code是一个数列集合,每个数使用二进位来表示,假设使用n位元来表示每个数好了,任 两个数之间只有一个位元值不同,例如以下为3位元的Gray Code:
000 001 011 010 110 111 101 100由定义可以知道,Gray Code的顺序并不是唯一的,例如将上面的数列反过来写,也是一组Gray
Code:
100 101 111 110 010 011 001 000

Gray Code是由贝尔实验室的Frank Gray在1940年代提出的,用来在使用PCM(Pusle CodeModulation)方法传送讯号时避免出错,并于1953年三月十七日取得美国专利。


最基本算法的解法:

由于Gray Code相邻两数之间只改变一个位元,所以可观 察Gray Code从1变0或从0变1时的

位置,假设有4位元的Gray Code如下:
0000 0001 0011 0010 0110 0111 0101 0100
1100 1101 1111 1110 1010 1011 1001 1000
观察奇数项的变化时,我们发现无论它是第几个Gray Code,永远只改变最右边的位元,如果
是1就改为0,如果是0就改为1。
观察偶数项的变化时,我们发现所改变的位元,是由右边算来第一个1的左边位元。

以上两个变化规则是固定的,无论位元数为何;

假设原始的值从0开始,格雷码产生的规律是:第一步,改变最右边的位元值;第二步,改变右起第一个为1的位元的左边位元;第三步,第四步重复第一步和第二步,直到所有的格雷码产生完毕(换句话说,已经走了(2^n) - 1 步)。

用一个例子来说明:
假设产生3位元的格雷码,原始值位 000
第一步:改变最右边的位元值: 00 1
第二步:改变右起第一个为1的位元的左边位元: 0 1 1
第三步:改变最右边的位元值: 010
第四步:改变右起第一个为1的位元的左边位元: 110
第五步:改变最右边的位元值: 111
第六步:改变右起第一个为1的位元的左边位元: 101
第七步:改变最右边的位元值: 100

如果按照这个规则来生成格雷码,是没有问题的,但是这样做太复杂了


所以只要判断位元的位置是奇数还是偶数,就

可以决定要改变哪一个位元的值,通过一个标识flag进行判断位置




#include "stdafx.h"
#include <math.h>
//#define METHOD1

#define METHOD2
#define MAXBITS 20

#define CHANBIT(x) x=(x=='0')?'1':'0'




int main()
{
char bina_bits[MAXBITS];
int n;//输入格雷码的位元个数
printf("please input the number of gray_code\n");
while(scanf("%d",&n))
{
if (n>MAXBITS)
{
printf("input n is more than the gray_code's maxbits\n");
   continue;
}
//输出格雷码的第一个元素 也就是全零
   for(int i=0;i<n;i++)
{
bina_bits[i]='0';
printf("%c",bina_bits[i]);
}
printf("\n");
//输出格雷码其它元素
int flag=1;//用来进行算法的变化的关键标识,也就是:第一步,改变最右边的位元值;第二步,改变右起第一个为1的位元的左边位元
while (1)
{
if (flag)
{
CHANBIT(bina_bits[n-1]);
}
else{
int i;
for (i=n-1;i>=0&&bina_bits[i]=='0';i--);//寻找右起第一个为1的位置
                if (i==0)
                {
break;
                }
CHANBIT(bina_bits[i-1]);
}
for (int i=0;i<n;i++)
{
printf("%c",bina_bits[i]);
}
printf("\n");
flag=abs(flag-1);
}
}
 return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值