【字符串】电话号码分身

题目:首先将电话号码中的每个数字加上8取个位,然后使用对应的大写字母代替 ("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"), 然后随机打乱这些字母,所生成的字符串即为电话号码对应的分身。现给你一个电话号码的分身,求出分身前的最小电话号码(允许前导0)

输入
4
EIGHT
ZEROTWOONE
OHWETENRTEO
OHEWTIEGTHENRTEO
输出
0
234
345

0345

思路:依次解码具有独一无二字符的数字,具有这样特点的数字有五个分别是FOUR(U),SIX(X),TWO(W),EIGHT(G),ZERO(Z),可以根据独特字符的个数直接判断有多少个相应的数字,例如有3个U那么就一定有3个FOUR...,解码完成这五个数字之后另外的数字也会由于这些数字的移除而具有了独一无二的字符。【来源牛客网:https://www.nowcoder.com/questionTerminal/493d71a992f44554a500ed818056e1a6】

代码一(用几个数组分别作为桶,存储字母或数字的出现次数)

#include<iostream>
#include<string>
#include<vector>
#include<memory>
using namespace std;
int alph[26];	//字符串中每个字母出现的个数
int numCnt[10];	//字符串中每个数字出现的个数
string numWord[10] = { "ZERO","ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE" };
//解码顺序和对应的关键字母
int keyNum[10] = { 0,2,4,6,8,1,7,9,5,3 };
char keyAlph[10] = { 'Z','W','U','X','G','O','S','N','V','T' };
//计算numCnt数组
void decode() {
	for (int i = 0; i < 10;i++) {
		while (alph[keyAlph[i] - 'A'] != 0) {
			for (char j : numWord[keyNum[i]])  alph[j - 'A']--;
			numCnt[keyNum[i]]++;
		}
	}
}
int main() {	
	int n;
	while (cin >> n) {
		string *strArr=new string[n];
		for (int i = 0; i < n; i++) cin >> strArr[i];
		for (int i = 0; i < n; i++) {
			string str = strArr[i];
			//one case
			memset(numCnt, 0, 10 * sizeof(numCnt[0]));
			memset(alph, 0, 26 * sizeof(alph[0]));
			for (char j : str) alph[j - 'A']++;
			decode();
			for (int j = 0; j < 10; j++)
				while (numCnt[(j + 8) % 10]-->0) cout << j;
			cout << endl;
		}
	}
}

代码二(与代码差不多,区别是计数方式,用map存储各字母的次数,然后依次计算各数字的次数)

while (T--)
{
	cin >> input;
	map<char, size_t> help;
	for (auto& t : input)
	{
		help[t] += 1;
	}
	vector<size_t> count(10);
	count[0] = help['Z'];            //ZERO
	count[2] = help['W'];            //TWO
	count[4] = help['U'];            //FOUR
	count[1] = help['O'] - count[0] - count[2] - count[4];     //ONE
	count[6] = help['X'];            //SIX
	count[8] = help['G'];            //EIGHT
	count[3] = help['T'] - count[2] - count[8];        //TRHEE
	count[5] = help['F'] - count[4];            //FIVE
	count[7] = help['V'] - count[5];            //SEVEN
	count[9] = help['I'] - count[6] - count[5] - count[8];   //NINE          //NINE
	vector<size_t> numsBefore(10);
	for (size_t i = 0; i<10; i++)
		numsBefore[(i + 2) % 10] = count[i];//号码还原
	for (size_t i = 0; i<10; i++)
	{
		for (int j = 0; j<numsBefore[i]; j++)
			cout << i;
	}
	cout << endl;
}


注意打印输出这部分代码,下标直接用加8取余来表示

for (int j = 0; j < 10; j++)
	while (numCnt[(j + 8) % 10]-->0) cout << j;

我之前的蹩脚写法:

for (int j = 0, k = 8; j < 10; j++, k = j + 8) {
	if (j + 8 >= 10) k = j - 2;
	while (numCnt[k] > 0) {
		cout << j;
		numCnt[k]--;
	}
}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值