当前位置: 首页 > 工具软件 > JAM > 使用案例 >

Jam的计数法

潘银龙
2023-12-01

题目描述

Jam是个喜欢标新立异的科学怪人。他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩。在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原先的顺序,排在前面的字母小于排在它后面的字母。我们把这样的“数字”称为Jam数字。在Jam数字中,每个字母互不相同,而且从左到右是严格递增的。每次,Jam还指定使用字母的范围,例如,从2到10,表示只能使用{b,c,d,e,f,g,h,i,j}这些字母。如果再规定位数为5,那么,紧接在Jam数字“bdfij”之后的数字应该是“bdghi”。(如果我们用U、V依次表示Jam数字“bdfij”与“bdghi”,则U<V< span>,且不存在Jam数字P,使U<P<V< span>)。你的任务是:对于从文件读入的一个Jam数字,按顺序输出紧接在后面的5个Jam数字,如果后面没有那么多Jam数字,那么有几个就输出几个。

输入格式

输入有2行,第1行为3个正整数,用一个空格隔开:s t w

(其中s为所使用的最小的字母的序号,t为所使用的最大的字母的序号。w为数字的位数,这3个数满足:1≤s<T< span>≤26, 2≤w≤t-s )

第2行为具有w个小写字母的字符串,为一个符合要求的Jam数字。

所给的数据都是正确的,不必验证。

输出格式

输出最多为5行,为紧接在输入的Jam数字后面的5个Jam数字,如果后面没有那么多Jam数字,那么有几个就输出几个。每行只输出一个Jam数字,是由w个小写字母组成的字符串,不要有多余的空格。

样例输入

2 10 5
bdfij

样例输出

bdghi
bdghj
bdgij
bdhij
befgh

开始的时候思路比较混乱,就想着用最简单的方法:从小到大遍历w个字母组合的所有情况,通过strcmp函数比较,如果出现大于原式的,count就+1直到count==5,但在写程序的过程中却发现这个想法难以实现,要实现所有组合的遍历,就必须使用嵌套for循环(也可能可以使用别的方法,但是我没有想到),但是字符串的长度是不确定的,所以没办法写出一个静态的嵌套for循环来遍历元素。在经过对样例输出的思考之后,我发现需要递增的只有字符串的最后一位,而其他位只需要在判断其后一位达到最大值时+1即可,这与判断最后一位达到最大值是相似的,所以可以采用同样的逻辑来实现。在非最后一位作出+1操作后,其后位只需要按照字母表进行改变就可以,然后将下标移到最后一位,继续开始递增,直到达到最大值,再重复上述操作。

#include <stdio.h>

int main() {
    char str[27] = { 0 };
    int s = 0;
    int t = 0;
    int w = 0;
    scanf("%d %d %d", &s, &t, &w);
    getchar();
    scanf("%s", str);
    char alpha[27] = { 0 };//将字母表存在数组中,以便查找
    for (int i = 1; i <= 26; i++) {
        alpha[i] = 'a' + i - 1;
    }
    int mark = 1;
    int count = 5;
    int tcpy = t;
    int sum = 1;
    for (int i = w - 1; i >= 0; i--, tcpy--) {//数组下标从最后一位开始,遍历整个数组
        if (str[i] + 1 < alpha[tcpy]) {//每当下标向前移动一位,则对应的最大字母也向前移动一位,所以使用与i对应的tcpy来控制最大值,如果第i位的字母+1后仍旧小于最大值,就说明这就是一个符合题目条件的输出
            if (i < w - 1) {//当i不是最后一位时,将该位的字母+1,并将其后的元素按字母表顺序赋值
                sum = 1;
                str[i] += 1;//该位字母+1
                for (int j = i+1; j <= w - 1; j++) {//按顺序赋值,如果i位改为b,则其后改为cde等
                    str[j] = str[i] + sum;
                    sum++;
                }
                printf("%s\n", str);
                count--;
                if (count == 0)//输出够5个就结束循环
                    break;
                i = w;//使下标回到末尾
                tcpy = t + 1;//tcpy也回到t
                continue;
            }
            str[i] += 1;//i为最后一位,就将i位的字母+1
            printf("%s\n", str);
            count--;
            if (count == 0)
                break;
            i++;//与i--抵消
            tcpy++;//与tcpy--抵消
            continue;
        }
        else if (str[i] + 1 == alpha[tcpy]) {//如果该位字母+1就是最大值
            str[i] += 1;//则直接使该位字母+1,即使i不是最后一位,由于其+1达到最大值,那么其后也必定达到了其对应的最大值
            printf("%s\n", str);
            count--;
            if (count == 0)
                break;
        }//大于最大值的情况就直接执行i--和tcpy--即可
    }
    return 0;
}

 类似资料: