0

我正在尝试解决一个问题,即在不使用 java 中长数字的二进制字符串的情况下找到汉明码。

我不明白我们怎么能做到这一点,我在很多地方搜索过,比如维基百科的解释和我在网上找到的这个,但它们都需要二进制字符串才能使用,但在这种情况下我不能使用它们。

我有一个代表输入二进制的长数字,现在我需要找到汉明码。

据我了解,我可以在该二进制文件中的位置 1、2、8 ... 处放置空白位置。现在我可以使用布尔值将 0 或 1 放在那个位置,该布尔值告诉我这是偶数还是奇数。

我使用字符串和列表编写了一个代码,但我需要在不使用字符串或列表的情况下这样做。

String text = new Scanner(System.in).next() ;
    int len = text.length() ;
    ArrayList codearray = new ArrayList() ;
    ArrayList pos_arr = new ArrayList() ;


    while (!(len + r + 1 <= Math.pow(2, r))) {
        r++;
    }


    System.out.println("Number of parity bits : "+r);

    for (int i=0 ; i<len + r  ; i++) {

        if (IsPowerTwo(i+1) ){
            codearray.add("?") ;
        }else {
            codearray.add(text.charAt(j));
            j++ ;
        }
    }


    System.out.println(codearray.toString());

    //to determine the position of parity bits
    for (int i=0 ; i< codearray.size() ; i++) {
        if (codearray.get(i) == "?") {
            int k ,s=1;
            // For Debugging.
            //System.out.println("Calculate at position " + (i+1) ) ;
            for (k = i ; k < codearray.size() ; k++){

                if (i==0) {
                    k++ ;
                    pos_arr.add(k);
                }else {

                    pos_arr.add(k+1);
                    if(s % (i+1) == 0) {
                        k += i+1 ;
                    }
                }
                s++ ;

            }

            checkOnes(pos_arr,codearray,i) ;
            pos_arr.clear();
        }


    }

    System.out.println("Code word: ");
    Arr_to_Str(codearray) ;
}

public static boolean IsPowerTwo(int num){
    int checked = num & num -1 ;
    if (checked == 0 ){
        return true ;
    }else {
        return false ;
    }

}
public static void checkOnes(ArrayList array, ArrayList codearray, int position ){

    int count =0;

    for (int i=0 ; i < array.size(); i++) {
        int index = (int) array.get(i) -1 ;
        if (codearray.get(index) == "?"  ) {
            codearray.set(index,0) ;
        }

        int num = Integer.parseInt(codearray.get(index).toString()) ;
        if (num == 1  ) {
            count++ ;
        }
        if(count % 2 ==0 ){
            codearray.set(position, 0) ;
        }else {
            codearray.set(position, 1) ;
        }

    }
}

public static void Arr_to_Str(ArrayList array){
    for (int i=0;i<array.size();i++){
        System.out.print(array.get(i));
    }
}

但这需要我使用二进制字符串或列表,我该如何处理长数字,比如 210。

我对位操作真的很陌生,因此我无法解决这个问题。我真的很感激任何帮助。

4

1 回答 1

2

汉明编码可以通过位操作来实现。使用字符串可能更简单。以下是关于实施的一些想法。

汉明编码算法的概要如下

input_val is a long int to encode
output_val_is the long int result
for s in 0..5
  count number of bits in input_val whose position has bit s set
  add to output_val the parity of this count
  add next 2^s bits from input_val to output_val

确实存在两个问题:获取一组特定位的奇偶性以及使用位移位创建输出。

计算给定模式上的设置位*

对于汉明编码,必须计算比特子集(模式)的奇偶校验。模式是第一步的 010101010101...01,第二步的 001100110...00110 等,并且可以在mask由步骤编号索引的数组中编码。掩码[0]=0x5555555555555555,掩码[1]=0x6666666666666666,掩码[2]=0xf0f0f0f0f0f0f0f0,掩码[3]=0xff00ff00ff00ff00等

为了得到这个奇偶校验,更简单的方法是计算比特数并得到这个计数的 lSB。java中有一个函数可以给出整数的位数。因此这里唯一需要的操作是

count=Integer.bitcount(input_val & masks[s]) ;

其中 s 是计算阶段数。

然后您必须添加到输出count & 0x1以添加计数的奇偶校验。

向整数加位

它与输入和输出值大小中的位数密切相关。为了简单起见,我假设您的数据都可以用 64 位编码。这意味着您有 6 个奇偶校验位,并且您的输入数据只是变量的一部分,并且 input_data 的 6 个 MSB 为零。

将整数的 LSB 添加voutput_val更简单的方法是将其添加到 result 的 MSB 位置,然后将其右移。添加 64 位后,一切都在适当的位置。注意 output_val 必须是无符号的以避免算术右移。

因此,要将 v 的 LSB 添加到 output_val,要做的操作是

output_val = (output_val >> 1) | (v<< 63);

v<<63 提取 LSB 并将其置于 MSB 位置。OR 添加到移位的结果。

要添加多个位(例如 k),可以使用

output_val = (output_val >> k) | (v<< (64-k));

所以最终的实现(改进)会是这样的

input_queue = input_val;
output_val = 0;
for (s=0; s<6;s++) {'
  count=Integer.bitcount(input_val & masks[s]) ; // compute parity
  output_val = (output_val >> 1) | (count << 63);// add parity to output
  output_val = (output_val >> (1<<s)) | (input_queue << (64-(1<<s)); 
                                   // add 2^s LSB of input to output
  input_queue >>=(1<<s);           // suppress 2^s bits form input_queue
}
于 2019-05-16T21:08:09.673 回答