/* 格雷碼 說明: Gray Code是一個數列集合 ,每個數使用二進位來表示 ,假設使用n位元來表示每個數好了 ,任兩個數之間只有一個位元值不同, 例如以下為3位元的Gray Code: 000 001 011 010 110 111 101 100 由定義可以知道,Gray Code的順序並不... ...
/* 格雷碼 說明: Gray Code是一個數列集合 ,每個數使用二進位來表示 ,假設使用n位元來表示每個數好了 ,任兩個數之間只有一個位元值不同, 例如以下為3位元的Gray Code: 000 001 011 010 110 111 101 100 由定義可以知道,Gray Code的順序並不是唯一的,例如將上面的數列反過來寫,也是一組GrayCode: 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 1000 1100 1101 1111 1110 1010 1011 1001 1000 觀察奇數項的變化時,我們發現無論它是第幾個Gray Code,永遠只改變最右邊的位元,如果是1就改為0,如果是0就改為1。 觀察偶數項的變化時,我們發現所改變的位元,是由右邊算來第一個1的左邊位元。 以上兩個變化規則是固定的,無論位元數為何;所以只要判斷位元的位置是奇數還是偶數,就可以決定要改變哪一個位元的值,為了 程式撰寫方便,將陣列索引 0當作最右邊的值,而在列印結果時,是由索引數字大的開始反向列印。 將2位元的Gray Code當作平面座標來看,可以構成一個四邊形,您可以發現從任一頂點出發,繞四邊形周長繞一圈,所經過的頂點座 標就是一組Gray Code,所以您可以得到四組GrayCode。 同樣的將3位元的Gray Code當作平面座標來看的話,可以構成一個正立方體,如果您可以從任一頂點出發,將所有的邊長走過,並不 重覆經過頂點的話,所經過的頂點座標順序之組合也就是一組Gray Code。 */ #include<stdio.h> #include<stdlib.h> #define MAXBIT 20 #define TRUE 1 #define CHANGE_BIT(x) x = ((x) == '0' ? '1':'0') #define NEXT(x) x = (1 - (x)) int main(void) { char digit[MAXBIT]; int i, bits, odd; printf("輸入位元數:"); scanf("%d", &bits); for(i = 0; i < bits; i++) { digit[i] = '0'; printf("0"); } printf("\n"); odd = TRUE; while(1) { if(odd) { CHANGE_BIT(digit[0]); } else { for(i = 0; i < bits && digit[i] == '0'; i++); if(i == bits - 1) { break; } CHANGE_BIT(digit[i+1]); } for(i = bits - 1; i >= 0; i--) { printf("%c", digit[i]); } printf("\n"); NEXT(odd); } return 0; }