今天学习计组时,学习到了一个新知识海明码,一般用于网络传输中对数据进行校验,如果出差,可以通过海明码这个算法实现查找一个出错位,通过取反的方式纠错,实现原理是在信息位中加入校验位,组成新的二进制串,形成海明码。
#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;
}