Time Limit: 10000ms
Case Time Limit: 1000ms
Memory Limit: 256MB
Description
For this question, your program is required to process an input string containing only ASCII characters between ‘0’ and ‘9’, or between ‘a’ and ‘z’ (including ‘0’, ‘9’, ‘a’, ‘z’).
Your program should reorder and split all input string characters into multiple segments, and output all segments as one concatenated string. The following requirements should also be met,
1. Characters in each segment should be in strictly increasing order. For ordering, ‘9’ is larger than ‘0’, ‘a’ is larger than ‘9’, and ‘z’ is larger than ‘a’ (basically following ASCII character order).
2. Characters in the second segment must be the same as or a subset of the first segment; and every following segment must be the same as or a subset of its previous segment.
Your program should output string “<invalid input string>” when the input contains any invalid characters (i.e., outside the '0'-'9' and 'a'-'z' range).
Input
Input consists of multiple cases, one case per line. Each case is one string consisting of ASCII characters.
Output
For each case, print exactly one line with the reordered string based on the criteria above.
Sample In
aabbccdd
007799aabbccddeeff113355zz
1234.89898
abcdefabcdefabcdefaaaaaaaaaaaaaabbbbbbbddddddee
Sample Out
abcdabcd
013579abcdefz013579abcdefz
<invalid input string>
abcdefabcdefabcdefabdeabdeabdabdabdabdabaaaaaaa
题目解析:
这道题是让分类排列输出,比如第一个aabbccdd,第一遍把输出所有的不同字符,第二遍输出剩下的所有字符……这个题目是输出的0-9和a-z,有其他字符的话,就会提示无效输入。
好了,题意就是这样,怎么去实现。第一遍输出所有不同的字符,每个输出一遍;第二遍输出剩下的所有字符,每个输出一遍……
也就是说:
1:某个字符i有m个,那么会输出m遍,在m+1遍的时候,该字符不再输出。:
2:输出的顺序也是按照ascii来输出的。
第一点的话,我们可以想到计数排序,第一趟遍历,统计每个数字出现的次数;第二点的话,就是输出数据每输出一遍,响应的计数就减小1。所以很容易想到了类似哈希表的方法来实现。这里为了方便,我们在函数中定义了一个max表示出现最多的次数。也就是我们最多遍历多少趟。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ReorderString(char *st);
int main(void)
{
int n;
char buf[100];
while(1){
scanf("%s",buf);
int result = ReorderString(buf);
if(!result)
printf("<invalid input string>");
printf("\n");
}
return 0;
}
int ReorderString(char *st)
{
int arr[36] = {0}; //定义伴随数组
int length = strlen(st); //判断字符串有多长
int index,max=0;
for(int i = 0;i < length;++i){ //遍历每一个字符,把在相应的数组中计数加1
index = st[i]-'0';
if(index>=0 && index < 10){ //先判断是不是数字字符
arr[index]++;
if(max < arr[index]) //找到数据中计数最大的值,方便后面遍历
max = arr[index];
}else{ //不是数字字符的话,下面先判断是不是字母字符,不是就退出程序
index = st[i] - 'a' + 10;
if(index >= 10 && index < 36){
arr[index]++;
if(max < arr[index])
max = arr[index];
}else
return 0;
}
}
for(int i = 0;i < max;++i){ //遍历输出,一共max趟输出
int j;
for(j = 0;j < 10;j++){ //如果是数字直接输出
if(arr[j] > 0){
printf("%d",j);
--arr[j];
}
}
for(;j < 36;j++){ //如果是字符,需要转换一下输出,注意这里用的是j不是arr[j]
if(arr[j] > 0){
printf("%c",j - 10 + 'a');
arr[j]--;
}
}
}
return 1;
}