C++:计算一个数的补码及其可能的不匹配数

C++:计算一个数的补码及其可能的不匹配数,c++,combinatorics,complement,C++,Combinatorics,Complement,我有点被我的算法卡住了,我需要一些帮助来解决我的问题。我想举个例子可以更好地解释我的问题 假设: d=4一个数字中允许的最大位数,2^4-1=15。 m_max=1允许的最大位不匹配数。 kappa=给定d和m的最大元素数,其中m在m_max中 其主要思想是,对于给定的数字x,以二进制为基数计算其补码数,并根据x补码数计算最大m_max不匹配的所有可能组合 现在程序开始从i=0扫描到15 对于i=0和m=0,kappa=\binom{d}{0}=1,这称为完美匹配 以位表示的可能组合,对于0:0

我有点被我的算法卡住了,我需要一些帮助来解决我的问题。我想举个例子可以更好地解释我的问题

假设:

d=4一个数字中允许的最大位数,2^4-1=15。 m_max=1允许的最大位不匹配数。 kappa=给定d和m的最大元素数,其中m在m_max中 其主要思想是,对于给定的数字x,以二进制为基数计算其补码数,并根据x补码数计算最大m_max不匹配的所有可能组合

现在程序开始从i=0扫描到15

对于i=0和m=0,kappa=\binom{d}{0}=1,这称为完美匹配 以位表示的可能组合,对于0:0000仅为1111

对于i=0和m=1,kappa=\binom{d}{1}=4一个不匹配 位的可能组合为:1000、0100、0010和0001

我的问题是把它推广到一般的d和m。我编写了以下代码:

#include <stdlib.h>
#include <iomanip>
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <stdint.h>
#include <vector>

namespace vec {
   typedef std::vector<unsigned int>  uint_1d_vec_t;
}

int main( int argc, char* argv[] ) {

   int counter, d, m;
   unsigned num_combination, bits_mask, bit_mask, max_num_mismatch;
   uint_1d_vec_t kappa;

   d = 4;
   m = 2;

   bits_mask = 2^num_bits - 1;
   for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
       counter = 0;
       for ( unsigned m = 0 ; m < max_num_mismatch ; m++ ) {
           // maximum number of allowed combinations
           num_combination = boost::math::binomial_coefficient<double>( static_cast<unsigned>( d ), static_cast<unsigned>(m) );
           kappa.push_back( num_combination );    
           for ( unsigned j = 0 ; j < kappa.at(m) ; j++ ) {
               if ( m == 0 )
                  v[i][counter++] = i^bits_mask; // M_0
               else {
                   bit_mask = 1 << ( num_bits - j );
                   v[i][counter++] = v[i][0] ^ bits_mask
               }
           }
       }
   }

   return 0;

}

由于无法将我的算法推广到m_max>1,因为我需要m_max不匹配m_max循环,在我最初的问题中,m在运行时之前是未知的。

我编写了一个代码,实现了我想要的功能,但由于我是新手,它有点难看。 我修复了m和d,尽管这段代码对于genral m和d来说可以很好地工作

主要思想很简单,假设我们想计算0到两个故障d=4,m=2的补码,我们将看到最大可能数由\sum_{i=0^2\binom{4}{i}=11给出。 4位0的补码是15 15:7 11 13 14的1位可能不匹配 有2位可能与15:35 6 9 10 12不匹配

我希望这个程序的输出是一个向量,里面有数字15 7 11 13 14 3 5 6 9 10 12

我希望这次我能更清楚地提出我的问题,尽管我也提供了解决方案。如果有人能在我的代码中指出改进和加快的方法,我会通知你

问候

#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <vector>

#define USE_VECTOR

namespace vec {
  #if defined(USE_VECTOR) || !defined(USE_DEQUE)
  typedef std::vector<unsigned int>  uint_1d_vec_t;
  typedef std::vector<uint_1d_vec_t> uint_2d_vec_t;
  #else
  typedef std::deque<unsigned int>   uint_1d_vec_t;
  typedef std::deque<uint_1d_vec_t>  uint_2d_vec_t;
  #endif
}

using namespace std;

void     get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned      max_num_unmatch , unsigned num_bits );
double   get_kappa( int m , int d );

int main( ) { 

    unsigned int num_elements , m , num_bits;

    num_elements = 16; 
    num_bits     = 4;   // 2^4 = 16
    m            = 2;

    double kappa = 0;
    for ( unsigned int i = 0 ; i <= m ; i++ )
        kappa += get_kappa( num_bits , i );

    vec::uint_2d_vec_t    Pointer(           num_elements   , vec::uint_1d_vec_t (kappa ,0 ) );

    get_pointers_vec( Pointer , num_elements , m , num_bits );

    for ( unsigned int i = 0 ; i < num_elements ; i++ ) {
        std::cout << setw(2) << i << ":";
        for ( unsigned int j = 0 ; j < kappa ; j++ )
            std::cout << setw(3) << Pointer[i][j];
        std::cout << std::endl;
    }

    return EXIT_SUCCESS;
}

double get_kappa( int n , int k ) {

    double kappa = boost::math::binomial_coefficient<double>( static_cast<unsigned>( n ), static_cast<unsigned>(k) );

    return kappa;
}

void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned   max_num_unmatch , unsigned num_bits ) {

    int counter;
    unsigned num_combination, ref_index, bits_mask, bit_mask;
    vec::uint_1d_vec_t kappa;

    bits_mask = pow( 2 , num_bits ) - 1;
    for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
        counter = 0;
        kappa.clear();
        ref_index = 0;

        for ( unsigned m = 0 ; m <= max_num_unmatch ; m++ ) {
            num_combination = get_kappa( num_bits , m ); // maximum number of allowed combinations
            kappa.push_back( num_combination );
            if (  m == 0 ) {
               v[i][counter++] = i^bits_mask; // M_0
            }
            else if ( num_bits == kappa.at(m) ) {

                     for ( unsigned k = m ; k <= num_bits ; k++ ) {
                         bit_mask = 1 << ( num_bits - k );
                         v[i][counter++] = v[i][ref_index] ^ bit_mask;
                     }
                }
                else {
                     // Find first element's index
                     ref_index += kappa.at( m - 2 );

                     for( unsigned j = 0 ; j < ( kappa.at(m - 1) - 1 ) ; j++ ) {
                         for ( unsigned k = m + j ; k <= num_bits ; k++ ) {
                             bit_mask = 1 << ( num_bits - k );
                             v[i][counter++] = v[i][ref_index] ^ bit_mask;
                         }
                         ref_index++;
                     }
                }
        }

    }
}

所以,你想要的是,给定两个位序列,比较它们并计算它们之间不同的位数?如果你对你要做的事情进行简短的非正式描述,阅读一个问题通常会容易得多。然后,你的精确算法、变量名和精确代码可以稍后在我们有上下文的情况下出现它,并且知道它的意思。“如果是这样的话,这比解决方案要容易得多。”Egave-你似乎用插入符号^作为算符操作符。C和C++中的卡雷特表示一个位异或运算。我用XOR运算来计算I的补码数。这是我首先搜索的。第一个0 MISM。atches,然后是1不匹配等等。@D.Shawley,一般来说,运算“~”是我需要的,但是如果你计算一个32位数字对一组最多只有4位的数字的补码,你就不会得到一个4位数字的补码……使用两个具有相同位长的数字之间的异或,给我我想要的结果。