簡介算法
在一組數的編碼中,若任意兩個相鄰的代碼只有一位二進制數不一樣,則稱這種編碼爲格雷碼(Gray Code),另外因爲最大數與最小數之間也僅一位數不一樣,即「首尾相連」,所以又稱循環碼或反射碼。在數字系統中,常要求代碼按必定順序變化。例如,按天然數遞增計數,若採用8421碼,則數0111變到1000時四位均要變化,而在實際電路中,4位的變化不可能絕對同時發生,則計數中可能出現短暫的其它代碼(1100、1111等)。在特定狀況下可能致使電路狀態錯誤或輸入錯誤。使用格雷碼能夠避免這種錯誤。格雷碼有多種編碼形式。數組
格雷碼(Gray Code)曾用過Grey Code、葛萊碼、格萊碼、戈萊碼、循環碼、反射二進制碼、最小差錯碼等名字,它們有的不對,有的易與其它名稱混淆,建議不要再使用這些曾用名。測試
格雷碼是一種具備反射特性和循環特性的單步自補碼,其循環和單步特性消除了隨機取數時出現重大錯誤的可能,其反射和自補特性使得對其進行求反操做也很是方便,因此,格雷碼屬於一種可靠性編碼,是一種錯誤最小化的編碼方式,所以格雷碼在通訊和測量技術中獲得普遍應用。
生成格雷碼 編碼
0 00
0 01
0 11
0 10
1 10
1 11
1 01
1 00
算法實現spa
一、遞歸實現code
/** * 遞歸生成二進制格雷碼 * 思路:一、得到n-1位生成格雷碼的數組 * 二、因爲n位生成的格雷碼位數是n-1的兩倍,故只要在n爲格雷碼的前半部分加0,後半部分加1便可。 * @param n 格雷碼的位數 * @return 生成的格雷碼數組 */ public static String[] GrayCode(int n) { //數組的大小是2的n次方,由於n位的格雷碼有2的n次方種排列 String[] grayCodeArr = new String[(int)Math.pow(2, n)]; if(n < 1) { System.out.println("你輸入的格雷碼位數有誤!"); } if(1 == n) { grayCodeArr[0] = "0"; grayCodeArr[1] = "1"; return grayCodeArr; } //n-1 位格雷碼的生成方式 String[] before = GrayCode(n-1); for(int i = 0 ; i < before.length ; i++){ grayCodeArr[i] = "0" + before[i]; grayCodeArr[grayCodeArr.length -1 - i] = "1" + before[i]; } return grayCodeArr; }
二、非遞歸實現blog
/** * 非遞歸生成二進制格雷碼 * 思路:一、得到n-1位生成格雷碼的數組 * 二、因爲n位生成的格雷碼位數是n-1的兩倍,故只要在n爲格雷碼的前半部分加0,後半部分加1便可。 * @param n 格雷碼的位數 * @return 生成的格雷碼數組 */ public static String[] GrayCode2(int n) { int num = (int)Math.pow(2, n);//根據輸入的整數,計算出此Gray序列大小 String[] s1 = {"0","1"};//第一個Gray序列 if(n < 1) { System.out.println("你輸入的格雷碼位數有誤!"); } for(int i=2;i<=n;i++){//循環根據第一個Gray序列,來一個一個的求 int p = (int)Math.pow(2, i);//到了第幾個的時候,來計算出此Gray序列大小 String[] si = new String[p]; for(int j=0;j<p;j++){//循環根據某個Gray序列,來一個一個的求此序列 if(j<(p/2)){ si[j] = "0" + s1[j];//原始序列前面加上"0" }else{ si[j] = "1" + s1[p-j-1];//原始序列反序,前面加上"1" } } s1 = si;//把求得的si,附給s1,以便求下一個Gray序列 } return s1; }
三、測試遞歸
public static void main(String[] args) { System.out.println("————————————————————遞歸實現————————————————"); String[] strArr = GrayCode(4); for(int i = 0 ; i < strArr.length ; i++) { System.out.println(strArr[i]); } System.out.println("——————————————————非遞歸實現————————————————"); String[] strArr2 = GrayCode2(4); for(int i = 0 ; i < strArr2.length ; i++) { System.out.println(strArr2[i]); } }
四、結果:字符串
————————————————————遞歸實現———————————————— 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000 ——————————————————非遞歸實現———————————————— 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000
致謝:感謝您的耐心閱讀!it