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;
}