【问题标题】:Binary representation in base (-2) shift left基数 (-2) 中的二进制表示左移
【发布时间】:2021-04-21 12:51:27
【问题描述】:

给定数字 x 在基数 (-2) 中的二进制表示,返回上限 (x/2) 在基数 (-2) 中的二进制表示。
O(1)中有解决方案吗?我试图想出一个“匹配”操作来向左移动,就像如果基数为 2 但找不到任何内容一样。

有没有比将 x 从基数 (-2) 转换为十进制,然后计算上限 (x/2) 并找到以基数 (-2) 为基数的二进制表示更好的方法?

【问题讨论】:

  • 提示:-1 = -2 + 1。这意味着(-1)(-2)^k = 1(-2)^k + 1(-2)^{k+1} 等。

标签: algorithm binary


【解决方案1】:

在基数 (-2) 中,数字表示为:

x = a[0](-2)^0 + a[1](-2)^1 + a[2](-2)^2 + ...a[k](-2)^k + ...

其中a[k] 等于 0 或 1。除以 x par 2 给出关系:

y = x/2 = -a[1](-2)^0 - a[2](-2)^1  -a[3](-2)^2  ... - a[k+1](-2)^k + ...
        =  b[0](-2)^0 + b[1] (-2)^1 + b[2](-2)^2  ...+ b[k](-2)^k + ...

系数 b[k] 现在等于 0 或 -1 而不是 0 或 1。

要将结果转换为合适的基 (-2) 表示,必须使用简单关系

-1 = -2 + 1

这意味着

(-1)(-2)^k = 1(-2)^k + 1(-2)^{k+1}

因此,b[k] 系数的简单迭代过程允许执行除以 2。

这提供了一个简单的 O(logn) 实现,迭代位。在下面的代码中, 我使用一个整数数组来表示基 (-2) 分解。使用整数而不是数组 使用相同的算法不会改变时间效率,只会减少使用的内存。

#include <iostream>
#include <vector>

void print (const std::vector<int> &v) {
    for (int i = v.size()-1; i >= 0; --i) {
        std::cout << v[i] << " ";
    }
    std::cout << std::endl;
}

//  conversion int -> base (-2)
std::vector<int> int2basem2 (int n) {
    std::vector<int> mbits (32, 0);
    int i = 0;
    int sign = 1;
    while (n != 0) {
        int remainder = n%2;
        if (remainder) {
            mbits[i] = 1;
            n -= sign;
        }
        n /= 2;
        i++;
        sign = -sign;
    }
    return mbits;
}

//  Conversion bas -2 -> int
basem22int (const std::vector<int> &mbits) {
    int n = 0;
    int base = 1;
    int size = mbits.size();
    for (int i = 0; i < size; ++i) {
        if (mbits[i]) n += base;
        base *= -2;
    }
    return n;
}

//  division by 2 in base -2
std::vector<int> div2 (const std::vector<int> &in) {
    int size = in.size();
    std::vector<int> div (size, 0);
    int carry_out = 0;
    for (int i = 0; i < size-1; ++i) {
        int j = i+1;
        div[i] = carry_out ^ in[j];
        carry_out = !carry_out && in[j];
    }
    div[size-1] = carry_out;
    return div;
}

int main() {
    int n = 1379;
    std::cout << "n = " << n << std::endl;
    auto mbits = int2basem2 (n);
    std::cout << "representation of n in base -2: \t";
    print (mbits);
    mbits = div2(mbits);
    int m = basem22int (mbits);
    std::cout << "representation of n/2 in  base -2: \t";
    print (mbits);
    std::cout << "n/2 = " << m << std::endl;
    
    return 0;
}

【讨论】:

    猜你喜欢
    • 2013-07-06
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    相关资源
    最近更新 更多