String reorder
题目大意:给你一个字符串,字符串包含'0'~'9','a'~'z'的字母(如果包含其他字母,则该字符串不合法),让你给该字符串重新排列并将其分割成几段,这些段需要满足一下几个条件:
1)短中的字符需要按照递增排列,这里指出'9'>'0','a' > '9','z'>'a'。
2)后一个段或者和前一个相等,或者是前一个段的子序列
让你输出排序后的字符串,题目如下:
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.
解题思路:
看了题目中给出的几个样例,想了一下,其实可以用贪心的思路来解。首先,可以按照字母排序,统计一下各个字母在字符串中出现的次数,然后重排的时候,可以按照字母顺序依次取一个字母,相应字母的计数减少一个,如果当前字母计数减少到0,这当前字母就不取,这个过程反复处理直到所有字母的计数都为0。
举个简单的例子吧:假设字符串是abaabccd,根据上述方法,对各个字母出现次数进行统计可得:a为3,b为2,c为2,d为1,在重排的时候,首先按照字母顺序进行取字符,首先a、b、c、d各取一个得到字符串abcd,这时计数变为a为2,b为1,c为1,d为0,第二次再取a、b、c,加上原先的字符串得到abcdabc,此 时计数变为a为1,b为0,c为0,d为0,第三次只能取得一个字符a,此时所有的字母计数都变为0,因此最终得到的字符串为abcdabca,符合题意要求。
下面是代码(由于输入的字符串中可能包含空格,不能用cin读入):
#include <iostream> #include <algorithm> #include <string> #include <map> using namespace std; int main() { string str; while(getline(cin,str).good()) { map<char, int> countMap; bool isValid = true; for(int i=0; i<str.size(); ++i) { if((str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'z')) { countMap[str[i]]++; }else { isValid = false; break; } } if(!isValid) { cout << "<invalid input string>" << endl; } else { string newStr = ""; int len = 0; while(len < str.size()) { map<char, int>::iterator it = countMap.begin(); for(; it!=countMap.end(); ++it) { if(it->second > 0) { newStr += it->first; --it->second; ++len; } } } cout << newStr << endl; } } return 0; }
上述代码复杂度为O(nlogn),其中n是字符串的长度。