微软2014实习生及秋令营技术类职位在线测试第一题:String reorder

如题,微软很重视算法的考察,同时也重视算法程序的实现,本题是笔者参加微软暑期实习的前期在线测试的一道编程题,得分是100,现与大家分享一下当时的实现算法!


本题翻译过来简述如下:输入的字符串只包括‘0’-‘9’和‘a’-‘z’ 之间ASCII字符,要求算法实现字符记录分割成多个子段,需满足1. 字符在每个子段依照ASCII码值属于严格递增序列,2. 后一个子段必须属于前一个子段的子集,即相同或者是真子集,3. 当输入包含不符合输入条件的字符时,输出 <invalid input string>


算法核心思想:取两个数组Num[10] 和 Char[26]分别记录合法输入字符的个数,这里利用一个经典的思想,即如果字符串中一个字符char c= ‘9’,则Num[c-'0']++ 即为其个数(数值本身可转化为下标值的经典思想,取材于霍夫曼字符压缩编码思想),这样遍历一遍输入字符串后即可记录所有合法字符的个数,然后按照 Num 和 Char这两个数组中记录每次循环输出非0个数的字符并把个数减1,循环次数由记录字符的最多个数决定,在记录Num 和 Char 的时候可以设置一个变量 maxCount来记录字符个数最多的个数。


当然,上述思想并不是最优的,因为如果仅有一个字符串 aaaaaaaaaaaa,则需循环12次之多,很是浪费,你看完后是否有改进的想法呢?不妨留言评论和各位网友一起分享


编译器: G++


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.


样例输入
aabbccdd
007799aabbccddeeff113355zz
1234.89898
abcdefabcdefabcdefaaaaaaaaaaaaaabbbbbbbddddddee
样例输出
abcdabcd
013579abcdefz013579abcdefz
<invalid input string>
abcdefabcdefabcdefabdeabdeabdabdabdabdabaaaaaaa



源代码如下

//source here
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
#define N 500

int main(void)
{
    char str[N];

	char Num[10];
	char Char[26];

	while(cin.getline(str,N))
	{
		for(int i=0; i<10; i++)Num[i]=0;
		for(int i=0; i<26; i++)Char[i]=0;

		int flag=1,count,maxCount=0;
		count = strlen(str);

		for(int i=0;i<count;i++)
		{
			char c = str[i];
			if(c < '0' || c >'z' || (c > '9' && c < 'a'))
			{
				cout<<"<invalid input string>"<<endl;
				flag = 0;
				break;
			}
			else if(c >= '0' && c <= '9')
			{
				int p = c - '0';
				Num[p] = Num[p]+1;
				if(Num[p] > maxCount) maxCount = Num[p];
			}
			else
			{
				int p = c - 'a';
				Char[p] = Char[p]+1;
				if(Char[p] > maxCount) maxCount = Char[p];
			}
		}

		if(flag == 1)
		{
			int i=0;
			while(i<maxCount)
			{
				for(int j=0;j<10;j++)
				{
					if(Num[j]>0)cout<<char(j+'0');
					Num[j] = Num[j]-1;
				}
				for(int k=0;k<26;k++)
				{
					if(Char[k]>0)cout<<char(k+'a');
					Char[k] = Char[k]-1;
				}
				++i;
			}

			cout<<endl;

		}

	}
  
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值