海明码检验和纠错

xiaoxiao2021-02-27  321

/* 海明码检验与纠错. */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; /* 测试样例 110010100000 0011101 1110110 011001011001 0001001 */ char s[105]; // 用来接收信息位字符串 char ans[1005]; //得出的海明码存储在这里 const int hehe[] = {1,2,4,8,16,32,64,128,256,512,1024}; //这个办法真是呵呵了。。。。 const int hehe_len = sizeof(hehe) / sizeof(int); //呵呵数组的长度,懒得算 int r_len; //校验位的位数 int k; //信息位个数 int step; //在海明码中信息位的最高下标。 int s1[105]; int s1_len; struct Node { int a[10]; //存储ri是由谁生成的(存下标) int len ; //a数组的长度 int val; //校验位的值 } r[105]; int pow(int b,int r_len) //幂运算 { int ret = 1; for(int i = 1; i <= r_len; ++i) ret *= b; return ret; } bool findPos(int n) //找到hehe中的数 { for(int i = 0; i < hehe_len; ++i) if(hehe[i] == n) return true; return false; } int f(char c) //char -> int { return c - '0'; } int zh() { int ret = 0; for(int i = 0;i < r_len;++i) if(s1[i]) ret += pow(2,i); return ret; } void solve() { int len_n = strlen(s + 1); for(k = len_n;k >= 0;--k) if(pow(2,len_n - k) >= len_n + 1) { r_len = len_n - k; break; } memset(ans,-1,sizeof ans); memset(r,0,sizeof r); for(int i = 1,j = len_n; i <= j; ++i,--j) //逆序字符串,以便对应I1,I2.... { char t = s[i]; s[i] = s[j]; s[j] = t; } //printf("%s\n",s); r_len = 0; for(int i = 1;i <= len_n;++i) { if(findPos(i)) { r[r_len++].val = f(s[i]); } } int i; for(step = 3,i = 1;i <= len_n;) { if(!findPos(step)) { if(findPos(i))++i; else ans[step++] = s[i++]; } else step++; } //printf("step = %d\n",step); for(int j = step - 1; j >= 3; --j) // 找出ri是由哪几位在一起生成的. { if(!findPos(j)) { int t = j; for(int l = hehe_len - 1; l >= 0 && t > 0; --l) { if(t >= hehe[l]) { t -= hehe[l]; r[l].a[r[l].len++] = j; } } } } for(int i = 1,j = 0;i <= max(step - 1,pow(2,r_len - 1));++i) { if(findPos(i)) { ans[i] = r[j++].val + '0'; } } s1_len = 0; for(int i = 0;i < r_len;++i) { s1[i] = r[i].val; for(int j = 0;j < r[i].len;++j) { s1[i] = s1[i] ^ f(ans[r[i].a[j]]); } } int pos = zh(); if(pos == 0) { printf("这个海明码没有错误!\n"); } else { ans[pos] == '0' ? ans[pos] = '1' : ans[pos] = '0'; printf("第%d位出现错误,改正后如下\n",pos); for(int i = max(step - 1,pow(2,r_len - 1));i >= 1 ;--i) printf("%c",ans[i]); printf("\n"); } } int main(){ while(~scanf("%s",s + 1)) solve(); return 0; }
转载请注明原文地址: https://www.6miu.com/read-5940.html

最新回复(0)