模拟海明码生成

/*
   生成海明码.
*/
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

/*
测试样例:

01101110 - - ->011001111001
1101    - - ->1100110
0010  - - ->0011001
*/
/*
   此程序没有代码优化,所以按照思路来代码比较凌乱。
   欢迎补充测试样例,和对此代码的提出的意见!
*/
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; //在海明码中信息位的最高下标。
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';
}

void solve()

{
    k = strlen(s + 1);
    //printf("hehe_len = %d\n",hehe_len);
    for(r_len = 3; r_len <= 100; ++r_len) //暴力寻找r_len
        if(pow(2,r_len) - 1 >= k + r_len)
            break;

    memset(ans,-1,sizeof ans);
    memset(r,0,sizeof r);

    for(int i = 1,j = k; i <= j; ++i,--j) //逆序字符串,以便对应I1,I2....
    {
        char t = s[i];
        s[i] = s[j];
        s[j] = t;
    }
    int i;
    for(step = 3,i = 1; i <= k; ++step) // 对应I1、I2。。。
        if(!findPos(step))
            ans[step] = s[i++];

    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 = 0;i < r_len;++i)
    {
        printf("i = %d \n",i);
        for(int j = 0;j < r[i].len;++j)
            printf("%d ",r[i].a[j]);
        printf("\n");
    }*/
    for(int i = 0; i < r_len; ++i)    //计算ri
    {
       // printf("i = %d\n",i);
        r[i].val = f(ans[r[i].a[0]]);
       // printf("r[i].val = %d\n",r[i].val);
        for(int j = 1; j < r[i].len; ++j){
            r[i].val = r[i].val ^ f(ans[r[i].a[j]]);
            //printf("r[i].val = %d\n",r[i].val);
        }
    }
    for(int i = 1,j = 0; i <= step; ++i)  //将计算出来的ri填到海明码中
        if(findPos(i))
        {
            ans[i] = r[j++].val + '0';
        }
    int cnt_k = k;
    int cnt_r = r_len - 1;
    printf("得出的海明吗如下:\n");
    for(int i = max(step - 1,pow(2,r_len - 1));i >= 1;--i)
        if(!findPos(i))
           printf("I%d ",cnt_k--);
        else
           printf("r%d ",cnt_r--);
    printf("\n");
    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;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值