Math 标准位置基到双射基的转换

Math 标准位置基到双射基的转换,math,numbers,base,Math,Numbers,Base,我们知道基于b的数字系统使用数字, 0,1,2,…,b-1。但是a使用数字,1,2,…,b。因此,基于4的标准数字系统序列如下所示 0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 (base-4, 16th number standard) 100 (base-4, 17th number standard) 101 . . . λ (base-4, 1st number, empty-string) 1 2 3 4 11 12 13 14 21 22

我们知道基于b的数字系统使用数字,
0,1,2,…,b-1
。但是a使用数字,
1,2,…,b
。因此,基于
4的
标准数字系统序列如下所示

0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33 (base-4, 16th number standard)
100 (base-4, 17th number standard)
101
.
.
.
λ (base-4, 1st number, empty-string)
1
2
3
4
11
12
13
14
21
22
23
24
31
32
33 (base-4, 16th number bijective)
34 (base-4, 17th number bijective)
41 
.
.
.
另一方面,基于
4的双射数字系统

0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33 (base-4, 16th number standard)
100 (base-4, 17th number standard)
101
.
.
.
λ (base-4, 1st number, empty-string)
1
2
3
4
11
12
13
14
21
22
23
24
31
32
33 (base-4, 16th number bijective)
34 (base-4, 17th number bijective)
41 
.
.
.
例如:

34152(双射基-5)=
3×54+4×53+1×52+5×51+2×1=2427(十进制)。
119A(在双射基-10中,“A”表示数字值10)=
1×103+1×102+9×101+10×1=1200
(十进制)

我想知道是否有任何简单的方法可以在同一个基中找到第n个双射值

比如说,


假设在
base-4
5th位置值=10(标准)但是5th位置值=11(双射)。任何伪代码都可以理解这个概念。

如果标准base-n系统中的数字包含no零,则该数字与双射base-n具有相同的表示形式

所以你需要在标准数字中寻找零。找到零后,用双射中的最大符号替换它,并向左递减元素

简单的例子:

10 decimal ->  A bijective because 0 becomes A and 1 decrements to zero
20 decimal -> 1A bijective because 0 becomes A and 2 decrements to 1
200 decimal ->  19A bijective (i.e. step 1: 1A0 step 2: 19A)
作为特例,必须处理零序列

简单的例子:

10 decimal ->  A bijective because 0 becomes A and 1 decrements to zero
20 decimal -> 1A bijective because 0 becomes A and 2 decrements to 1
200 decimal ->  19A bijective (i.e. step 1: 1A0 step 2: 19A)
你也可以这样看

200 decimal is constructed as 2*100 + 0*10 + 0*1 = 200 decimal
对于双射,你不能有零,所以你要:

19A bijective is constructed as 1*100 + 9*10 + 10*1 = 200 decimal
要完成更复杂的示例,请执行以下操作:

110 decimal ->  AA bijective (i.e. step 1: 10A step 2: AA)

此例程实现转换。(解析为@4386427的方法)如果需要另一个版本,其中100(base 4 std)->41(base 4 bij')然后使用
-D NO_EMPTY_STRING

#include <stdio.h>
#include <string.h>
void print_be_digits(const char *prefix, const unsigned char *le_num, size_t len)
{
  size_t i;
  printf("%s", prefix);
  for(i=0; i<len; i++)
  {
    printf("%d ", (int)le_num[len-i-1]);
  }
  printf("\n");
}

void nth_bij(int n, int k)
{
  ssize_t i;
  size_t std_len;
  size_t bij_len;
  size_t work;
  unsigned char le_std_digits[256];
  unsigned char le_bij_digits[256];

  //convert to standard radix-k digits
  work = n;
  for(std_len = 0; work; std_len++)
  {
    le_std_digits[std_len] = work % k;
    work /= k;
  }

  print_be_digits("  std: ", le_std_digits, std_len);

  //convert standard to bij
  memcpy(le_bij_digits, le_std_digits, std_len);
  bij_len = std_len;

  #ifdef NO_EMPTY_STRING
  // Step 1: increment LSd
  le_bij_digits[0]++;
  #endif

  // Step 2: borrow on zeros
  // scan back from the end
  for(i=bij_len-1; i>= 0; i--)
  {
    //if we find a zero, borrow, and ripple toward MSd as necessary
    if(le_bij_digits[i] == 0)
    {
      size_t j;

      //Ripple borrow toward MSd, as necessary
      for(j=i+1; j<bij_len; j++)
      {
        le_bij_digits[j-1] = k; //k is the radix

        if(--le_bij_digits[j])
        {
          break;
        }
      }//end ripple

      //adjust bij_len if we rippled to the end
      if(j == bij_len)
      {
        bij_len--;
      }
    }
  }//end scan
  print_be_digits("  bij: ", le_bij_digits, bij_len);
}
为我的版本编译:

$ gcc -D NO_EMPTY_STRING bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
  std: 1 0 0
  bij: 4 1

Test: 8 decimal (->base 2):
  std: 1 0 0 0
  bij: 1 2 1

Test: 13 decimal (->base 2):
  std: 1 1 0 1
  bij: 2 2 2

Test: 2427 decimal (->base 5):
  std: 3 4 2 0 2
  bij: 3 4 1 5 3

Test: 1200 decimal (->base 10):
  std: 1 2 0 0
  bij: 1 1 10 1
为@4386427的版本编译:

$ gcc bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
  std: 1 0 0
  bij: 3 4

Test: 8 decimal (->base 2):
  std: 1 0 0 0
  bij: 1 1 2

Test: 13 decimal (->base 2):
  std: 1 1 0 1
  bij: 2 2 1

Test: 2427 decimal (->base 5):
  std: 3 4 2 0 2
  bij: 3 4 1 5 2

Test: 1200 decimal (->base 10):
  std: 1 2 0 0
  bij: 1 1 9 10

以你的声誉和长期的会员身份,你应该更清楚这一点。你应该知道如何创建一个。零在你的“双射”系统中是如何表示的?此外,双射系统如何表示位置系统中对应于
33
100
133
333
的数字?当双射数字系统@Jonathanleffler时,没有零。有趣的是,这样的数字系统仍然有效地具有前导零。例如,以5为基数的双射式中
3/5
的答案是什么?其结果似乎是,第n个位置的双射值仅比相应的标准值大1。不能简单地在标准rep中计算,然后通过添加1进行转换吗?您希望如何在C程序中存储这些数字?作为字符串?他忘记了
+1
。否则100->101->41.在base-4中
100
将转到
34
双射(即100 base4是16位小数(1*16+0*4+0*1)和双射34(3*4+4=16位小数))@DavidBowling-我们能同意base-4中的
34
是16位小数吗?因为它是3*4+4*1=16十进制?标准base-4中的
100
也是16位小数?@DavidBowling-这是因为OP没有将
空字符串
作为双射词的一个位置来计算。所以OP把双射视为{1,2,3,4,11,…},而OP把标准基-4视为{0,1,2,3,10,…},所以我可能误解了OP问题。我的建议映射到相同的值之间,而不是位置之间。。。嗯…@SazzadHissainKhan-在这种情况下,我的答案应该是你所看到的:-)这只是转换过程中的一个中间步骤。我马上将代码粘贴到这里。亲爱的各位,我为误导性的问题道歉,请查看我更正的帖子。实际上我忘记了双射数字序列的空字符串。在base-4中,33 std=33双射,100 std=34双射。看这里是的,我必须改变我处理相邻0序列的方式。这与第一篇文章很接近,但有细微的不同。我同意这是一次非常愉快的旅行。我已经有一段时间没有那么有趣的编程了。