积极到消极&&负基数为负数

时间:2016-06-22 17:34:50

标签: c++ algorithm base

我们得到一个由0和1组成的数组。它们代表基数为-2的数字。例:     A =(1,1,0,1,0)     in decimal =( - 2)^ 0 *(1)+( - 2)^ 1 *(1)+( - 2)^ 2 *(0)+( - 2)^ 3 *(1)+( - 2 )^ 4 *(0)= 1 +( - 2)+ 0 +( - 8)+ 0 = -9

现在,我们需要在基数-2中将-9转换为9。到目前为止,这是我的代码:

vector<int> negative_base(vector<int> &A) {
    //first convert number to decimal base
    int n = 0;
    long count = A.size();
    int power_of_two = 1;
    for(int i=0;i<count;i++){
        n+=power_of_two*A[i];
        power_of_two = power_of_two*-2;
    }
    cout<<"number: "<<n<<endl;
    vector<int> base_minus_two;
    n=-n;
    while(n!=0){
        int x;
        if(n<0) {

            x = n%2;
            if(x!=0) x+=2;
            n = (n/-2) +1;

        } else {
            x = n%2;
            n = n/-2;
        }
        base_minus_two.push_back(x);
    }
    return base_minus_two;
}

我被要求返回最短的0和1的链。但是,我的代码并不总是如此。对于此示例,它生成(1,0,1,1,1)。我认为这个例子很好,但在某些情况下,它给了我很长的链条,而其他更短的版本。在某些情况下,它会产生错误的结果。例如,如果我们必须将23转换为-23,那么我们得到{1,0,0,0,0,0,1,1}。但是,此数字不等于-23,而是等于-63。所以,我的计算肯定会出现问题。我遵循最简单的基本转换算法,在这种算法中你一直保持分数,直到你达到零为止,在你继续时保存向量中的所有余数。这是一个负面的基础,所以结果*( - 2)+余数应该给你以前的东西。

-23 = (-2) *  12  + 1
 12 = (-2) * (-6) + 0
- 6 = (-2) *   3  + 0
  3 = (-2) * (-1) + 1
 -1 = (-2) *   1  + 1
  1 = (-2) *   0  + 1

结果应该是(1,0,0,1,1,1),但我正如我所说的那样得到{1,0,0,0,0,0,1,1}。我的代码出了什么问题?

2 个答案:

答案 0 :(得分:1)

我发现代码有什么问题。这是新版本:

vector<int> negative_base(vector<int> &A) {
//first convert number to decimal base
int n = 0;
long count = A.size();
int power_of_two = 1;
for(int i=0;i<count;i++){
    n+=power_of_two*A[i];
    power_of_two = power_of_two*-2;
}
cout<<"number: "<<n<<endl;
vector<int> base_minus_two;
n=-n;
while(n!=0){
    int x;
    if(n<0){
        x = n%2;
        if(x!=0){ x+=2;
        n = (n/-2) +1;
        }else{
            n = (n/-2);
        }

    }else{
        x= n%2;
        n = n/-2;

    }
    cout<<"n: "<< n <<" x: "<<x<<endl;
    base_minus_two.push_back(x);

}
return base_minus_two;
}

答案 1 :(得分:0)

测试余数是否为负的逻辑是错误的(你可以拆分为子函数)。

struct div_with_positive_remainder_t
{
    int quot;
    int rem;
};

div_with_positive_remainder_t div_with_positive_remainder(int x, int y)
{
    if (y == 0)
        throw std::runtime_error("division by zero");
    int r = x % y;
    if (r < 0) {
        r += std::abs(y);
    }
    int q = (x - r) / y;
    return {q, r};
}

std::vector<int> to_negbase(int n, int negbase = -2)
{
    std::vector<int> res;

    while (n != 0) {
        auto div = div_with_positive_remainder(n, negbase);
        res.push_back(div.rem);
        n = div.quot;
    }
    return res;
}

int to_int(const std::vector<int> &digits, int base = -2) {
    int res = 0;
    int power = 1;
    for (auto digit : digits){
        res += power * digit;
        power *= base;
    }
    return res;
}

std::vector<int> negative_base(const std::vector<int> &v)
{
    return to_negbase(-to_int(v));
}

Demo