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

发布于 2024-08-15 12:06:30 字数 1916 浏览 9 评论 0原文

我的算法有点困难,我需要一些帮助来解决我的问题。我认为一个例子可以更好地解释我的问题。

假设:

  • d = 4(数字中允许的最大位数,2^4-1=15)。
  • m_max = 1(允许不匹配位的最大数量)。
  • kappa =(给定 d 和 m 查找的最大元素数,其中 m 在 m_max 中)

主要思想是对于给定数字 x,计算其补数(以二进制为基础)以及最多可达的所有可能组合m_max 与 x 补数的数量不匹配。

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

  • 对于 i = 0 且 m = 0,kappa = \binom{d}{0} = 1 (这称为完美匹配) 可能的位组合只有 1111(对于 0: 0000)。

  • 对于 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;

}

我陷入了 v[i][counter++] = v[i][0] ^ bits_mask 行,因为我无法将我的算法推广到 m_max>1,因为我需要 m_max 不匹配 m_max 循环,并且在我原来的问题中,m 在运行时之前是未知的。

I got a bit stuck with my algorithm and I need some help to solve my problem. I think an example would explain better my problem.

Assuming:

  • d = 4 (maximum number of allowed bits in a number, 2^4-1=15).
  • m_max = 1 (maximum number of allowed bits mismatches).
  • kappa = (maximum number of elements to find for a given d and m, where m in m_max)

The main idea is for a given number, x, to compute its complement number (in binary base) and all the possible combinations for up to m_max mismatches from x complement's number.

Now the program start to scan from i = 0 till 15.

  • for i = 0 and m = 0, kappa = \binom{d}{0} = 1 (this called a perfect match)
    possible combinations in bits, is only 1111 (for 0: 0000).

  • for i = 0 and m = 1, kappa = \binom{d}{1} = 4 (one mismatch)
    possible combinations in bits are: 1000, 0100, 0010 and 0001

My problem was to generalize it to general d and m. I wrote the following code:

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

}

I got stuck in the line v[i][counter++] = v[i][0] ^ bits_mask since I was unable to generalize my algorithm to m_max>1, since I needed for m_max mismatches m_max loops and in my original problem, m is unknown until runtime.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩于岁月 2024-08-22 12:06:30

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

主要思想很简单,假设我们想要计算 0 到两次失败的补码 (d= 4,m=2),我们将看到最大可能性数由 \sum_{i = 0 给出)^2\binom{4}{i} = 11
0 的补码(4 位)是 15
有 1 位可能不匹配(从 15 开始):7 11 13 14
有 2 位可能不匹配(从 15 开始): 3 5 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++;
                     }
                }
        }

    }
}

i wrote a code that do what i want, but since i am newbie, it is a bit ugly.
i fixed m and d although this code would work fine for genral m and d.

the main idea is simple, assuming we would like to compute the complement of 0 up to two failure (d= 4,m=2), we will see that max number of possibilities is given by \sum_{i = 0)^2\binom{4}{i} = 11.
The complement to 0 (at 4 bits) is 15
With 1 bit possible mismatch (from 15): 7 11 13 14
with 2 bits possible mismatches (from 15): 3 5 6 9 10 12

i wanted that the output of this program will be a vector with the numbers 15 7 11 13 14 3 5 6 9 10 12 inside it.

i hope that this time i am more clear with presenting my question (although i also supplied the solution). I would appreachiate if someone could point out, in my code, ways to improve it and make it faster.

regards

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

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文