Код Хэмминга

Материал из Викиучебника — открытых книг для открытого мира

Код Хэ́мминга— вероятно, наиболее известный из первых самоконтролирующихся и самокорректирующихся кодов. Построен применительно к двоичной системе счисления. Позволяет исправлять одиночную ошибку (ошибка в одном бите) и находить двойную

Код на C++

//code by Melyohin Nikita

  1. include <iostream>
  2. include <vector>
  3. 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;

}