什么算法将数字27映射到BBC

时间:2014-04-12 11:21:04

标签: c algorithm combinatorics

澄清混淆 - 我想编写一个将数字映射到以下字母组合列表的函数。

我的问题最好用下表说明。

A   1
B   2
C   3
AA  4
AB  5
AC  6
BA  7
BB  8
BC  9
CA  10
CB  11
CC  12
AAA 13
AAB 14
AAC 15
ABA 16
ABB 17
ABC 18
ACA 19
ACB 20
ACC 21
BAA 22
BAB 23
BAC 24
BBA 25
BBB 26
BBC 27

我想设计一个能够将给定数字映射到此here表左列的函数。我已经尝试过首先在字母上分配数字。

A = 0
B = 1
C = 2

这允许我形成下表(Cn - 列号,从右到左)。

C3  C2  C1  Number

        0   1
        1   2
        2   3
    0   0   4
    0   1   5
    0   2   6
    1   0   7
    1   1   8
    1   2   9
    2   0   10
    2   1   11
    2   2   12
0   0   0   13
0   0   1   14
0   0   2   15
0   1   0   16
0   1   1   17
0   1   2   18
0   2   0   19
0   2   1   20
0   2   2   21
1   0   0   22
1   0   1   23
1   0   2   24
1   1   0   25
1   1   1   26
1   1   2   27

所以这看起来像一个递归循环类型算法,但我无法弄清楚如何将它放在代码中。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

无论是谁(用户:n.m。)撰写评论消失的人,这只是基数为3的计数,除了所有数字都被+1抵消。数字实际上代表A = 0,B = 1,C = 2

因此BBC =('B'+ 1)* 3 ^ 2 +('B'+ 1)* 3 +('C'+ 1)= 2 * 9 + 2 * 3 + 3 = 27

fromInt()的伪代码,Antoine已经给你了。同样的想法:

char* fromInt(int n) {
  result = ""
  working_val = (n-1)
  while (working_val>0) {
    Prepend to result the digit "CAB"[ working_val % 3 ]
    working_val /= 3
  }
  return result
}

严格来说,我们并不关心捕获Antoine注意到的特殊情况0,因为你的列表没有0的表示。

答案 1 :(得分:2)

#include <stdio.h>
#include <string.h>

int toInt(const char *str, int acc) {
    if(*str)
        return toInt(++str, acc * 3 + *str - 'A' + 1);
    else
        return acc;
}

char *fromInt(int n, char *outbuff){
    char* p = outbuff;
    while(n){
        *p++ = 'A' + ((n % 3 == 0)? 3 : n % 3) - 1;
        n = (n - 1) / 3;
    }
    *p = '\0';
    return strrev(outbuff);//strrev isn't ANSI C

}

int main(void) {
    char buff[] = "BBC";
    int x = toInt(buff, 0);
    printf("%d\n", x);
    printf("%s\n", fromInt(x, buff));
    return 0;
}

答案 2 :(得分:2)

这是一种base-3系统,但数字是1(A),2(B)和3(C),没有0.

转换公式来自此表示通常是

3^n*a_n + 3^(n-1)*a_{n-1} + ... + 3^0*a_0

逆转换就像常规转换为base 3一样,唯一的区别是使用了修改后的余数函数:

int modified_remainder(m, n)
{
   int answer = m % n;
   if (answer == 0) answer = n;
   return answer;
}

现在给定数字m,其表示的最后一位数字为

a_0 = modified_remainder(m, 3)

前一个是

m_1 = (m - a_0) / 3; // m-a_0 is always divisible by 3
a_1 = modified_remainder(m_1, 3)

下一个是

m_2 = (m_1 - a_1) / 3
a_2 = modified_remainder(m_2, 3)

等等。你在m_k < n时停止。

尝试验证这些说法,这是一个很好的练习。