编码技术大全
目錄
一,格雷碼
1,力扣 89. 格雷編碼
2,格雷碼簡介
3,格雷碼和九連環
一,格雷碼
1,力扣 89. 格雷編碼
n 位格雷碼序列 是一個由 2n 個整數組成的序列,其中:
每個整數都在范圍 [0, 2n - 1] 內(含 0 和 2n - 1)
第一個整數是 0
一個整數在序列中出現 不超過一次
每對 相鄰 整數的二進制表示 恰好一位不同 ,且
第一個 和 最后一個 整數的二進制表示 恰好一位不同
給你一個整數 n ,返回任一有效的 n 位格雷碼序列 。
示例 1:
輸入:n = 2
輸出:[0,1,3,2]
解釋:
[0,1,3,2] 的二進制表示是 [00,01,11,10] 。
- 00 和 01 有一位不同
- 01 和 11 有一位不同
- 11 和 10 有一位不同
- 10 和 00 有一位不同
[0,2,3,1] 也是一個有效的格雷碼序列,其二進制表示是 [00,10,11,01] 。
- 00 和 10 有一位不同
- 10 和 11 有一位不同
- 11 和 01 有一位不同
- 01 和 00 有一位不同
示例 2:
輸入:n = 1
輸出:[0,1]
?
提示:
1 <= n <= 16
思路:
利用分治算法,由n位格雷碼可以直接得到n+1位格雷碼。
代碼:
//翻轉vector template<typename T> vector<T> frev(const vector<T>& v) {vector<T> ans;ans.resize(v.size());for (int i = 0; i < v.size(); i++)ans[i] = v[v.size() - 1 - i];return ans; } //vector加一個數 template<typename T1, typename T2> void fjia(vector<T1>& v, T2 n) {for (int i = v.size() - 1; i >= 0; i--)v[i] += n; } //2個vector拼接起來 template<typename T> vector<T> join(const vector<T>& v1, const vector<T>& v2) {vector<T>ans(v1.size() + v2.size());copy(v1.begin(), v1.end(), ans.begin());copy(v2.begin(), v2.end(), ans.begin() + v1.size());return ans; } class Solution { public:vector<int> grayCode(int n) {if (n <= 0) {return vector<int>(1);}vector<int> v = grayCode(n - 1);vector<int> v2 = frev(v);fjia(v2, 1 << n - 1);return join(v, v2);} };2,格雷碼簡介
上面的題目已經把格雷碼的要求說的很清楚了,輸出解釋里面也提到了格雷碼不是唯一的。
我上面代碼得到的是最典型的格雷碼(和上面圖片內相同),一般格雷碼默認指的就是這種。
對于典型格雷碼,可以直接算出每個數的格雷碼:
對于n位二進制數a1 a2 ... an,表示成n位格雷碼g1 g2 ... gn,
則,這里的+表示異或
例如11的四位二進制是1011,則格雷碼是1110,即14
用數學歸納法很容易證明這個規律是對的。
(1)二進制轉格雷碼
void gray(int n, int k) {vector<int>v;for (int i = 0; i < k; i++) {v.push_back(n % 2);n /= 2;}v.push_back(0);for (int i = k; i; i--)cout << (v[i] ^ v[i - 1]); }int main() {int n, k;cin >> n >> k;gray(n, k);return 0; }輸入:9 4
輸出:1101? 即9的四位格雷碼
(2)格雷碼轉二進制
void grayToInt(int n, int k) {vector<int>v;for (int i = 0; i < k; i++) {v.push_back(n % 2);n /= 2;}int tmp;cout << (tmp = v[k - 1]);for (int i = k - 2; i >= 0; i--)cout << (tmp = (v[i] ^ tmp)); }int main() {int n, k;cin >> n >> k;grayToInt(n, k);return 0; }輸入:14 4
輸出:1011? 即四位格雷碼14表示的是11
3,格雷碼和九連環
九連環按照每個環在上面就是1在下面就是0編號,可以得到一個九位二進制數。
每次只能修改一位(一個環),最終的目標是變成000000000
神奇的是,九連環的最快解法(即沒有無效操作,不考慮最后2個環一起操作)就是在從2^9-1到0的一個遍歷。
grayToInt(511,9)的結果是101010101,即341,所以九連環需要341步。
也可以根據gray函數直接把九連環的步驟打出來:
void gray(int n, int k) {vector<int>v;for (int i = 0; i < k; i++) {v.push_back(n % 2);n /= 2;}v.push_back(0);for (int i = k; i; i--)cout << (v[i] ^ v[i - 1]);cout << " "; }int main() {for (int n = 341; n >= 0; n--) {gray(n, 9);if (n % 5 == 0)cout << endl;}return 0; }輸出:
111111111 ?111111110
111111010 ?111111011 ?111111001 ?111111000 ?111101000
111101001 ?111101011 ?111101010 ?111101110 ?111101111
111101101 ?111101100 ?111100100 ?111100101 ?111100111
111100110 ?111100010 ?111100011 ?111100001 ?111100000
110100000 ?110100001 ?110100011 ?110100010 ?110100110
110100111 ?110100101 ?110100100 ?110101100 ?110101101
110101111 ?110101110 ?110101010 ?110101011 ?110101001
110101000 ?110111000 ?110111001 ?110111011 ?110111010
110111110 ?110111111 ?110111101 ?110111100 ?110110100
110110101 ?110110111 ?110110110 ?110110010 ?110110011
110110001 ?110110000 ?110010000 ?110010001 ?110010011
110010010 ?110010110 ?110010111 ?110010101 ?110010100
110011100 ?110011101 ?110011111 ?110011110 ?110011010
110011011 ?110011001 ?110011000 ?110001000 ?110001001
110001011 ?110001010 ?110001110 ?110001111 ?110001101
110001100 ?110000100 ?110000101 ?110000111 ?110000110
110000010 ?110000011 ?110000001 ?110000000 ?010000000
010000001 ?010000011 ?010000010 ?010000110 ?010000111
010000101 ?010000100 ?010001100 ?010001101 ?010001111
010001110 ?010001010 ?010001011 ?010001001 ?010001000
010011000 ?010011001 ?010011011 ?010011010 ?010011110
010011111 ?010011101 ?010011100 ?010010100 ?010010101
010010111 ?010010110 ?010010010 ?010010011 ?010010001
010010000 ?010110000 ?010110001 ?010110011 ?010110010
010110110 ?010110111 ?010110101 ?010110100 ?010111100
010111101 ?010111111 ?010111110 ?010111010 ?010111011
010111001 ?010111000 ?010101000 ?010101001 ?010101011
010101010 ?010101110 ?010101111 ?010101101 ?010101100
010100100 ?010100101 ?010100111 ?010100110 ?010100010
010100011 ?010100001 ?010100000 ?011100000 ?011100001
011100011 ?011100010 ?011100110 ?011100111 ?011100101
011100100 ?011101100 ?011101101 ?011101111 ?011101110
011101010 ?011101011 ?011101001 ?011101000 ?011111000
011111001 ?011111011 ?011111010 ?011111110 ?011111111
011111101 ?011111100 ?011110100 ?011110101 ?011110111
011110110 ?011110010 ?011110011 ?011110001 ?011110000
011010000 ?011010001 ?011010011 ?011010010 ?011010110
011010111 ?011010101 ?011010100 ?011011100 ?011011101
011011111 ?011011110 ?011011010 ?011011011 ?011011001
011011000 ?011001000 ?011001001 ?011001011 ?011001010
011001110 ?011001111 ?011001101 ?011001100 ?011000100
011000101 ?011000111 ?011000110 ?011000010 ?011000011
011000001 ?011000000 ?001000000 ?001000001 ?001000011
001000010 ?001000110 ?001000111 ?001000101 ?001000100
001001100 ?001001101 ?001001111 ?001001110 ?001001010
001001011 ?001001001 ?001001000 ?001011000 ?001011001
001011011 ?001011010 ?001011110 ?001011111 ?001011101
001011100 ?001010100 ?001010101 ?001010111 ?001010110
001010010 ?001010011 ?001010001 ?001010000 ?001110000
001110001 ?001110011 ?001110010 ?001110110 ?001110111
001110101 ?001110100 ?001111100 ?001111101 ?001111111
001111110 ?001111010 ?001111011 ?001111001 ?001111000
001101000 ?001101001 ?001101011 ?001101010 ?001101110
001101111 ?001101101 ?001101100 ?001100100 ?001100101
001100111 ?001100110 ?001100010 ?001100011 ?001100001
001100000 ?000100000 ?000100001 ?000100011 ?000100010
000100110 ?000100111 ?000100101 ?000100100 ?000101100
000101101 ?000101111 ?000101110 ?000101010 ?000101011
000101001 ?000101000 ?000111000 ?000111001 ?000111011
000111010 ?000111110 ?000111111 ?000111101 ?000111100
000110100 ?000110101 ?000110111 ?000110110 ?000110010
000110011 ?000110001 ?000110000 ?000010000 ?000010001
000010011 ?000010010 ?000010110 ?000010111 ?000010101
000010100 ?000011100 ?000011101 ?000011111 ?000011110
000011010 ?000011011 ?000011001 ?000011000 ?000001000
000001001 ?000001011 ?000001010 ?000001110 ?000001111
000001101 ?000001100 ?000000100 ?000000101 ?000000111
000000110 ?000000010 ?000000011 ?000000001 ?000000000
總結
- 上一篇: iku爱酷后台开放匿名代理服务 | Wo
- 下一篇: 绝代反向指标——丘吉尔 炒股第二天就崩盘