如何从任意大的任意基地转换为另一个

时间:2014-02-12 14:30:08

标签: algorithm math base

我想要做的是将一个字符串从一个“字母”转换为另一个,就像在基数之间转换数字一样,但更抽象和任意数字。

例如,将“255”从字母“0123456789”转换为字母“0123456789ABCDEF”将导致“FF”。一种方法是将输入字符串转换为整数,然后再将其转换回来。像这样:(伪代码)

int decode(string input, string alphabet) {
  int value = 0;
  for(i = 0; i < input.length; i++) {
    int index = alphabet.indexOf(input[i]);
    value += index * pow(alphabet.length, input.length - i - 1);
  }
  return value;
}

string encode(int value, string alphabet) {
  string encoded = "";
  while(value > 0) {
    int index = value % alphabet.length;
    encoded = alphabet[index] + encoded;
    value = floor(value / alphabet.length);
  }
  return encoded;
}

这样decode("255", "0123456789")返回整数255,encode(255, "0123456789ABCDEF")返回"FF"

这适用于小字母,但我希望能够使用base 26(所有大写字母)或base 52(大写和小写)或base 62(大写,小写和数字),以及可能超过一百位。从理论上讲,上面的算法可以用于这样的字母表,但实际上,我遇到了整数溢出,因为当你开始做62 ^ 100时数字变得如此之快。

我想知道的是,如果有一个算法可以像这样进行转换而不必跟上这样巨大的整数吗?也许是在处理整个输入字符串之前开始输出结果的方法?

我的直觉告诉我,这可能是可能的,但我的数学技能缺乏。任何帮助将不胜感激。

StackOverflow上有一些类似的问题,但似乎没有一个正是我正在寻找的。

2 个答案:

答案 0 :(得分:2)

将数字存储在任意基数中的一般方法是将其存储为整数数组。最低限度,一个数字将由一个基数和int数组(或短或长,取决于您想要的基数范围)表示,代表该基数中的不同数字。

接下来,您需要在该任意基础上实现乘法。

之后你可以实现转换(线索:如果x是旧的基数,在新的基数中计算x,x ^ 2,x ^ 3,...。之后,将旧基数的数字乘以这些数字,然后加起来。)

答案 1 :(得分:0)

类似Java的伪代码:

ArbitraryBaseNumber source = new ArbitraryBaseNumber(11,"103A"); 
ArbitraryBaseNumber target = new ArbitraryBaseNumber(3,"0");

for(int digit : base3Num.getDigitListAsIntegers()) { // [1,0,3,10]
    target.incrementBy(digit);
    if(not final digit) {
        target.multiplyBy(source.base);
    }
}

当然,仍然存在的挑战是使用incrementBy(int)multiplyBy(int)方法实现ArbitraryBaseNumber。基本上要做到这一点,你在代码中完成了小学生在纸上添加和长时间乘法时所做的事情。谷歌,你会找到例子。