C 将索引从自定义字母表转换为序列

C 将索引从自定义字母表转换为序列,c,algorithm,C,Algorithm,我想生成一个函数,它接受一个整数x和字符数组,并返回一个字符串x步进序列 例如,考虑字母“ABC”,它会产生字符串A、B、C、AA、AB、AC、BA、BB、BC、CA、CB、CC、AAA、AAB…如果传入索引0,我希望输出为“a”;同样,如果传入索引34,我希望输出为“cbb” 对于字母“0123456789”,我希望字符串0、1、2、3、4、5、6、7、8、9、00、01、02、03、04、05、06、07、08、09、10、11 到目前为止,我已经写了以下内容,但是我被困在21-23、33-

我想生成一个函数,它接受一个整数x和字符数组,并返回一个字符串x步进序列

例如,考虑字母“ABC”,它会产生字符串A、B、C、AA、AB、AC、BA、BB、BC、CA、CB、CC、AAA、AAB…如果传入索引0,我希望输出为“a”;同样,如果传入索引34,我希望输出为“cbb”

对于字母“0123456789”,我希望字符串0、1、2、3、4、5、6、7、8、9、00、01、02、03、04、05、06、07、08、09、10、11

到目前为止,我已经写了以下内容,但是我被困在21-23、33-35、45-47等案例中,这些案例的行为发生了偏差,我已经盯着这些案例看了好几个小时了,没有一个模式向我跳出来(关于字母表的大小和索引)。起初我没有注意到这个问题,使用了一个更大的字母表,直到它在我的程序中产生了更大的问题

我不会假装下面的代码是优雅的,遵循良好的实践,也没有经过优化-在这个阶段,我真的只是想了解这个模式的正确实现,并一直在改变各地的事情,试图解决这个问题。如果变量名混淆,请提前道歉。此外,这是一个常见的模式/问题吗?我曾试图搜索类似的算法,但一直无法找到任何与脑海中出现的术语

unsigned long power(int num, int exp)
{
    int i;
    unsigned long ret = num;

    if (exp == 0) return 1;

    for (i = 1; i < exp; i++)
    {
        ret *= num;
    }

    return ret;
}

unsigned long sumsqr(int base, int exp)
{
    unsigned long sum;

    for (sum = 0; exp > 0; exp--)
    {
        sum += power(base, exp);
    }

    return sum;
}

char * generateStringT(unsigned long index, char * charmap)
{
    unsigned long scaler;
    unsigned long remainder;
    unsigned long divisor;
    int base;
    int exponent;
    int factor;  
    char * buffer;
    char * string;
    int i;

    buffer = malloc(sizeof(char) * 100);
    i = 0;

    base = strlen(charmap);

    exponent = 0;
    divisor = 0;
    remainder = index;

    while(sumsqr(base, exponent) <= index)
    {
        exponent++;
    }
    exponent--;

    factor = exponent;

    while(factor >= 0)
    {
        divisor = power(base, factor);
        if ((factor > 1) && (exponent > 0))
        divisor += power(base, factor-1);

        scaler = remainder/divisor;

        remainder = remainder - scaler * divisor;
        printf("%lu,", scaler);

        if ((factor == exponent) && (exponent > 0)) scaler--;
        buffer[i++] = charmap[scaler];

        factor--;
    }


    buffer[i++] = '\0';

    string = malloc((strlen(buffer) + 1) * sizeof(char));
    strcpy(string, buffer);
    free(buffer);

    return string;
}
无符号长幂(int-num,int-exp)
{
int i;
无符号长ret=num;
如果(exp==0)返回1;
对于(i=1;i0;exp--)
{
总和+=功率(基数,exp);
}
回报金额;
}
char*generateStringT(无符号长索引,char*charmap)
{
无符号长定标器;
无符号长余数;
无符号长除数;
int-base;
整数指数;
智力因素;
字符*缓冲区;
字符*字符串;
int i;
缓冲区=malloc(sizeof(char)*100);
i=0;
base=strlen(charmap);
指数=0;
除数=0;
余数=指数;
while(sumsqr(基数,指数)=0)
{
除数=幂(基,因子);
如果((系数>1)和(&(指数>0))
除数+=幂(基数,因子-1);
定标器=余数/除数;
余数=余数-定标器*除数;
printf(“%lu”,定标器);
如果((因子==指数)和(&(指数>0))定标器--;
缓冲区[i++]=charmap[scaler];
因子--;
}
缓冲区[i++]='\0';
string=malloc((strlen(buffer)+1)*sizeof(char));
strcpy(字符串、缓冲区);
自由(缓冲);
返回字符串;
}
不是修复(乍一看,您的代码使用了类似的想法——但更复杂!),但这是我用来将整数索引转换为
a、b、c
-格式页码的代码:

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

char *number_alpha (char *dest, int value, char *base)
{
    char *ddest = dest, *startdest = dest, swop;

    if (value < 0)
    {
        value = -value;
        *dest = '-';
        startdest++;
        ddest++;
    }
    value++;
    do
    {
        *ddest = base[((value-1) % strlen(base))];
        ddest++;
        value = (value-1)/strlen(base);
    } while (value > 0);
    *ddest = 0;
    ddest--;
    while (ddest > startdest)
    {
        swop = *ddest;
        *ddest = *startdest;
        *startdest = swop;
        startdest++;
        ddest--;
    }
    return dest;
}

int main (int argc, char **argv)
{
    int number;
    char result[256];

    if (argc != 3)
    {
        printf ("usage: [number] [string]\n");
        return -1;
    }

    number = strtol (argv[1], NULL, 10);
    number_alpha (result, number, argv[2]);
    printf ("%d in 'base' %s yields %s\n", number, argv[2], result);

    return 0;
}
--


有关其他语言的几个实现,请参阅。他们似乎专注于递归解决方案,而我的解决方案是线性的(无论是好是坏)。

你在那里试图做的看起来像是一个基本转换,但实际上略有不同。任何基数中的任何数字都可以被视为在所表示的数字后面有无限多个前导零(或该基数中的最低有效数字)。你的情况并非如此

在您的例子中,您非常重视所表示的数字的位数,这使得索引它们稍微复杂一些。有了数学中的基数,就可以很容易地计算出任意基数中所代表数字的指数
b
;也就是说,对于每个数字,
乘以
提升到
顺序
的幂的总和。在您的例子中,索引建立了一个额外的
sum_{k=1}{amount.of.digits.on.our.number-1}基^k
。如果我们从索引中减去这个加法,我们的任务就会变得相当简单

可以使用
sumsqr
函数计算该加法

在这里,我对您的代码做了一点修改,并在修改处添加了注释,这可以解决许多问题,正如您所期望的:

// added this
remainder -= sumsqr(base, exponent);

while (factor >= 0)
{
    divisor = power(base, factor);

    // commented this out
    // if ((factor > 1) && (exponent > 0))
    //  divisor += power(base, factor - 1);

    scaler = remainder/divisor;

    remainder = remainder - scaler * divisor;
    printf("%lu,", scaler);

    // commented this out
    // if ((factor == exponent) && (exponent > 0))
    //  scaler--;

    buffer[i++] = charmap[scaler];

    factor--;
}
我不确定你想用我注释掉的零件做什么。我的猜测是,您试图将
除数
增加我前面提到的差值,而不是将
索引
余数
减少该值


希望这能有所帮助。

“。这是一个常见的模式/问题吗?”是的:使用
a、b、c
的页面编号通常遵循此模式(例如,在PDF中使用)。@Jongware很有道理!这让我想到了一些有用的东西——谢谢!谢谢你的回答!用my函数包装您的解决方案似乎可以在不做任何更改的情况下完成相应的工作。我真的很感谢您的时间贡献,现在我应该从您的解决方案中得到足够的指导,以分析我的算法并改进它。再次感谢!