代码题--C++--小米--电话号码分身--用字母识别电话号码
题目描述
继MIUI8推出手机分身功能之后,MIUI9计划推出一个电话号码分身的功能:首先将电话号码中的每个数字加上8取个位,然后使用对应的大写字母代替 ("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"), 然后随机打乱这些字母,所生成的字符串即为电话号码对应的分身。
输入描述:
第一行是一个整数T(1 ≤ T ≤ 100)表示测试样例数;接下来T行,每行给定一个分身后的电话号码的分身(长度在3到10000之间)。
输出描述:
输出T行,分别对应输入中每行字符串对应的分身前的最小电话号码(允许前导0)。
示例1
输入
4
EIGHT
ZEROTWOONE
OHWETENRTEO
OHEWTIEGTHENRTEO
输出
0
234
345
0345
解题思路:用两个数组,一个数组b是保存数字的,一个数组n是存放输入的字符串的,然后先将字符串中每个字符代表的数字,当成下标位,然后存储字符个数,最后输出加8后各位置代表的数字。
代码如下:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int t ,i,s;
cin >> t;
char n[10004];
int b[10] = {0,0,0,0,0,0,0,0,0,0};
while( t --)
{
memset(b,0,sizeof(b));
cin >> n;
s = strlen(n);
for(i = 0; i< s; i++) {
if(n[i] == 'Z') b[0]++;//0对应2
if(n[i] == 'O') b[1]++;
if(n[i] == 'W') b[2]++;//2对应4
if(n[i] == 'H') b[3]++;
if(n[i] == 'U') b[4]++;//4对应6
if(n[i] == 'F') b[5]++;
if(n[i] == 'X') b[6]++;//6对应8
if(n[i] == 'S') b[7]++;
if(n[i] == 'G') b[8]++;//8对应0
if(n[i] == 'I') b[9]++;
}
b[1] = b[1] - b[0] - b[2] - b[4];//1对应3
b[3] = b[3] - b[8];//3对应5
b[5] = b[5] - b[4];//5对应7
b[7] = b[7] - b[6];//7对应9
b[9] = b[9] - b[8] - b[5]- b[6];//9对应1
while(b[8]--) {
printf("%c",'0');
}
while(b[9]--) {
printf("%c",'1');
}
while(b[0]--) {
printf("%c",'2');
}
while(b[1]--) {
printf("%c",'3');
}
while(b[2]--) {
printf("%c",'4');
}
while(b[3]--) {
printf("%c",'5');
}
while(b[4]--) {
printf("%c",'6');
}
while(b[5]--) {
printf("%c",'7');
}
while(b[6]--) {
printf("%c",'8');
}
while(b[7]--) {
printf("%c",'9');
}
printf("\n");
}
return 0;
}
解法二:用数组bfr保存输入的字符串,然后将输入的各个字母代表的数字在数组中保存,比如A就是下标0的位置,然后这个位置的数字++,然后将每个字母在哪些数字中含有,用式子表达出来,在存放数字的数组numCount中,利用特定字母个数判断有哪些数字,所以存数字的时候要用字符个数减去这个单词的其他字母。
实例讲解比如输入:ZERO
名称 | 值 | 类型 | |
---|---|---|---|
▶ | letterCount | 0x010fd6c0 {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1} | int[26] |
名称 | 值 | 类型 | |
---|---|---|---|
numCount[0] | 1 | int |
在存numCount[0] = letterCount[25]; //(1)的时候,可以识别到字母Z有一个,值为1,所以将数组numCount[0]置为1,
然后识别到numCount[3] = letterCount[17] - numCount[4] - numCount[0]; //(2)的时候,可以识别到 letterCount[17]为1,代表有一个字母为R,然后 numCount[4]=letterCount[20]=0,因为没有字母U,而numCount[0] = letterCount[25]=1,是有一个字母Z的,最后numCount[3] = 1-0-1 =0;所以就可以避免重复录入数据。
然后识别到numCount[1] = letterCount[14] - numCount[0] - numCount[4] - numCount[2]; //(3)的时候,可以识别到 letterCount[14]为1,代表有一个字母为O,然后 numCount[4]=letterCount[20]=0,numCount[2] = letterCount[22]=0,因为没有字母W,而numCount[0] = letterCount[25]=1,是有一个字母Z的,最后numCount[3] = 1-0-1-0 =0;所以就可以避免重复录入数据。
#include "stdio.h"
#include "stdlib.h"
int main() {
char bfr[10001];
int T;
scanf("%d", &T);
int letterCount[26];
while (T--) {
scanf("%s", bfr);
memset(letterCount, 0, 26 * sizeof(int));
char* p;
for (p = bfr;*p;p++) {
letterCount[*p - 'A']++;
}
int numCount[10], nump, np;
/*
(1)Z=a0
(2)R=a0+a3+a4
(3)O=a0+a1+a2+a4
(4)T=a2+a3+a8
(5)W=a2
(6)H=a3+a8
(7)F=a4+a5
(8)U=a4
(9)X=a6
(10)V=a5+a7
(11)N=a1+a7+a9+a9
(12)G=a8
*/
numCount[0] = letterCount[25]; //(1)
numCount[2] = letterCount[22]; //(5)
numCount[4] = letterCount[20]; //(8)
numCount[5] = letterCount[5] - numCount[4]; //(7)
numCount[3] = letterCount[17] - numCount[4] - numCount[0]; //(2)
numCount[1] = letterCount[14] - numCount[0] - numCount[4] - numCount[2]; //(3)
numCount[6] = letterCount[23]; //(9)
numCount[7] = letterCount[21] - numCount[5]; //(10)
numCount[8] = letterCount[6]; //(12)
numCount[9] = (letterCount[13] - numCount[1] - numCount[7]) / 2; //(11)
nump = 0;
np = 0;
for (p = bfr;nump < 10;p++, np++) {
while (np >= numCount[(nump + 8) % 10]) {
nump++;
np = 0;
if (nump >= 10) {
*p = '\0';
break;
}
}
if (nump >= 10) break;
*p = '0' + nump;
}
printf("%s\n", bfr);
}
}
结果,2+8=10,取个位是0,ZERO代表0。