海明码检验和纠错

/*
   海明码检验与纠错.
*/
#include 
#include 
#include 

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;
}


你可能感兴趣的:(模拟)