Код Хэмминга
Внешний вид
Код Хэ́мминга— вероятно, наиболее известный из первых самоконтролирующихся и самокорректирующихся кодов. Построен применительно к двоичной системе счисления. Позволяет исправлять одиночную ошибку (ошибка в одном бите) и находить двойную
Код на C++
//code by Melyohin Nikita
- include <iostream>
- include <vector>
- include <map>
using namespace std;
vector<vector<int>>getTable(int n, int add){
//генерация матрицы преобразования
vector<vector<int>> table(add, vector<int>(n));
int nowPow = 1;
for (int i = 0; i < add; i++){
int skip = nowPow - 1;
int now = 0, set = 1;
for (int j = 0; j < min(n, skip); j++){
table[i][j] = 0;
}
for (int j = skip; j < n; j++){
if (now == nowPow){
set ^= 1;
now = 0;
}
table[i][j] = set;
now++;
}
nowPow *= 2;
}
return table;
}
int main(){
int n;
cin >> n; //ввод длины строки
string s;
cin >> s;
if (n > s.size()){
//дописывание начальных нулей (если это необходимо)
string nws = "";
for (int i = 0; i < n - s.size(); i++){
nws += '0';
}
for (int i = 0; i < s.size(); i++){
nws += s[i];
}
s = nws;
}
if (n < s.size()){
cout << "incorrect string\n";
return 0;
}
int now = 1, add = 0; //add - количество контрольных бит
map<int, bool>isPow2;
//поиск количества контрольных бит
while (1){
if (now < n){
isPow2[now] = 1;
now *= 2;
n++;
add++;
}
else break;
}
now = 0;
vector<int>ans(n); //здесь будет храниться код Хемминга
for (int i = 0; i < ans.size(); i++){
if (!isPow2[i+1]){
ans[i] = int(s[now++] - '0');
}
else{
ans[i] = 0;
}
}
auto table = getTable(n, add);
cout << "__________\n\ntable:\n\n";
for (int i = 0; i < add; i++){
for (int j = 0; j < n; j++){
cout << table[i][j];
}
cout << "\n";
}
//подсчет контрольных битов
int power = 1;
now = 0;
while (power < n){
int sum = 0;
for (int i = 0; i < n; i++){
sum += ans[i] * table[now][i];
}
ans[power - 1] = sum % 2;
now++;
power*=2;
}
//вывод результата
cout << "\n__________\n\nResult:\n\n";
for (int i : ans){
cout << i;
}
cout << "\n";
for (int i = 0; i < n; i++){
if (isPow2[i + 1]){
cout << "-"; //подчеркнуты контрольные биты
}
else cout << " ";
}
return 0;
}