【问题标题】:Base Conversion Problem碱基转换问题
【发布时间】:2010-02-19 06:15:55
【问题描述】:

我现在正在尝试将整数转换为字符串,但遇到了问题。

我已经编写了大部分代码并且可以正常工作,但是在携带到下一个地方时它有一个小缺陷。很难描述,所以我举个例子。使用 base 26 和由小写字母组成的字符集:

0 = "a"
1 = "b"
2 = "c"

...

25 = "z"
26 = "ba" (这应该等于 "aa")

在某些情况下似乎会跳过字符集中零位的字符。

让我感到困惑的是我的代码没有任何问题。我一直在研究这个太久了,我仍然无法弄清楚。

char* charset = (char*)"abcdefghijklmnopqrstuvwxyz";
int charsetLength = strlen(charset);

unsigned long long num = 5678; // Some random number, it doesn't matter
std::string key

do
{
    unsigned int remainder = (num % charsetLength);
    num /= charsetLength;

    key.insert(key.begin(), charset[remainder]);

} while(num);

我感觉函数在返回零的模数上出错了,但我一直在研究这个问题,我不知道它是如何发生的。欢迎提出任何建议。

编辑:生成的字符串是小端的事实与我的应用程序无关。

【问题讨论】:

  • 旁注:您对数据类型的选择是可疑的。为什么charset 不是const char*? (这会让你摆脱 C 风格的演员表。)为什么 charsetlength 不是 std::size_t - 这是 std::strlen() 返回的类型。如果numunsigned long long,那么(在常见平台上)将其除以26 的结果如何适合unsigned int
  • 我或多或少地写了这段代码作为一个例子,尽管你的观点是有效的和赞赏的。

标签: c++ modulo base itoa


【解决方案1】:

如果我正确理解您想要的内容(excel 用于列的编号,A、B、.. Z、AA、AB、...),这是一个能够表示从 1 开始的数字的基础符号。26数字的值是 1、2、... 26,基数是 26。所以 A 的值是 1,Z 的值是 26,AA 的值是 27...偏移量为 1 而不是 0。

#include <string>
#include <iostream>
#include <climits>

std::string base26(unsigned long v)
{
    char const digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    size_t const base = sizeof(digits) - 1;
    char result[sizeof(unsigned long)*CHAR_BIT + 1];
    char* current = result + sizeof(result);
    *--current = '\0';

    while (v != 0) {
        v--;
        *--current = digits[v % base];
        v /= base;
    }
    return current;
}

// for testing
#include <cstdlib>

int main(int argc, char* argv[])
{
    for (int i = 1; i < argc; ++i) {
        unsigned long value = std::strtol(argv[i], 0, 0);
        std::cout << value << " = " << base26(value) << '\n';
    }
    return 0;
}

运行 1 2 26 27 52 53 676 677 702 703 给出

1 = A
2 = B
26 = Z
27 = AA
52 = AZ
53 = BA
676 = YZ
677 = ZA
702 = ZZ
703 = AAA

【讨论】:

  • 这个例子给了我修复我自己的代码所需要的东西,谢谢!
【解决方案2】:

你的问题是 'a' == 0。

换句话说,'aa' 不是答案,因为它实际上是 00。'ba' 是正确答案,因为 b = '1',所以它以 26 为底数为 10,即十进制的 26。

您的代码是正确的,只是您似乎误解了它。

【讨论】:

  • 啊,是的。这是有道理的。关于如何解决这个问题的任何想法?
  • 与将十进制表示的错误表示为“10”而不是“00”的方法相同。换句话说,没有什么可以修复的。您的代码输出正确的值。例如,在 0 1 2 3 4 5 6 7 8 9 之后得到 10,而不是十进制的 00。
【解决方案3】:

我认为你应该让 a=1 和 z=0 得到 abc...z 就像十进制的 1234...90

与十进制比较:9 后面是 10 而不是 01!

【讨论】:

    【解决方案4】:

    要在我的系统上编译 Aprogrammers 解决方案(我使用的是 gcc 版本 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3),我需要添加标头;#include &lt;climits&gt; #include&lt;cstdlib&gt;

    【讨论】:

    • 感谢您指出这一点。我已经对 Stuart 的回答进行了编辑以添加这些内容。以后当你看到这样的答案有问题时,我建议你点击“编辑”按钮直接编辑答案,而不是发布另一个答案,以确保每个人都能看到你的更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2010-11-17
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多