C++:计算一个数的补码及其可能的不匹配数
我有点被我的算法卡住了,我需要一些帮助来解决我的问题。我想举个例子可以更好地解释我的问题 假设: 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。我编写了以下代码: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
#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位数字的补码……使用两个具有相同位长的数字之间的异或,给我我想要的结果。