今天學習計組時,學習到了一個新知識海明碼,一般用于網絡傳輸中對資料進行校驗,如果出差,可以通過海明碼這個算法實作查找一個出錯位,通過取反的方式糾錯,實作原理是在資訊位中加入校驗位,組成新的二進制串,形成海明碼。
#include <algorithm>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
/*漢明碼的生産和檢測一位錯誤*/
class HanmingCode {
public:
/*構造函數*/
HanmingCode(std::string& _inforcode) {
this->inforlen = _inforcode.size();
for (auto& now : _inforcode) {
this->inforcode.push_back(now - '0');
}
}
/*生成校驗位長度*/
void Generateveriflen() {
for (int i = 0;; i++) {
if ((1 << i) - 1 >= inforlen + i) {
this->veriflen = i;
return;
}
}
}
/*生成漢明碼長度*/
void Generatehanmlen() {
Generateveriflen();
this->hanmlen = this->inforlen + this->veriflen;
return;
}
/*生成校驗碼*/
void Generateverifcode() {
for (int i = 0; i < this->veriflen; i++) {
this->verifcode.push_back(0);
}
int k = 0, m = 0;
/*收集非校驗位*/
for (int i = 1; i <= this->hanmlen; i++) {
if (i == (1 << k)) {
k++;
} else {
int tmp = i, ks = this->veriflen - 1;
while (tmp) {
if (tmp >= (1 << ks)) {
tmp -= (1 << ks);
verifcode[ks] ^= inforcode[m];
}
ks--;
}
m++;
}
}
}
/*生成海明碼*/
void Generatehanmcode() {
this->Generatehanmlen();
this->Generateverifcode();
for (int i = 1, j = 0, k = 0, s = 0; i <= hanmlen; i++) {
if (((1 << s)) == i) {
hanmcode.push_back(verifcode[j++]);
s++;
} else {
hanmcode.push_back(inforcode[k++]);
}
}
for (auto& x : hanmcode) {
std::cout << x;
}
std::cout << std::endl;
}
private:
int inforlen; /*資訊碼長度*/
int veriflen; /*校驗碼長度*/
int hanmlen; /*漢明碼長度*/
std::vector<int> hanmcode; /*漢明碼*/
std::vector<int> inforcode; /*資訊碼*/
std::vector<int> verifcode; /*校驗碼*/
};
int main() {
/*[1][2][3][4]....按照從做往右大小遞增順序編寫,最後生成的漢明碼是從左往右順序的答案*/
std::string ans = "1010";
HanmingCode test(ans);
test.Generatehanmcode();
return 0;
}