【2014微软实习生笔试】1:字符排序


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








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值