<pre name="code" class="cpp">
http://wenku.baidu.com/link?url=4NYfyGHC3RpzJhuI4ipsfNzDwvK_OZFjDCXQXoxCzAvpU_6PirwVRUKMxG2Q7Et5IKayi5pgMQxDm4vthg7j09KVGkDMeWzNN1lvSAVRDvW
第一题:
MIUI9计划推出一个电话号码分身的功能:首先将电话号码的每个数字加上8取个位,然后使用对应的大写字母代替(“ZERO”,"ONE"...."NINE")然后随机乱打这些字母,所生产的字符串纪委电话号码对应的分身。
输入:第一行是一个整数T,表示测试样例数目;接下来T行,每行给定一个分身后的电话号码的分身。
样例:
输入:
4
EIGHT
ZEROTWOONE
OHWETENRTEO
OHEWTIEGTHENRTEO
输出:
0
234
345
0345
一开始用了很多方法,switch case选择,但是这样不能辨别出混乱的字母顺序。
后来经某位网友的启发(http://bbs.youkuaiyun.com/topics/392023704),我联想到了前几天看编程之美2.3该节所讲的删除算法,稍加改进得到了下列代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int k,count=0,num;
int data[100]; char *str1;
int ch[26] = { 0 };//数组ch[26]初始化为零
scanf("%d",&num);
//存出字符串数组
char **str = (char **)malloc(num*sizeof(char*));
for (int a = 0; a < num; a++)
{
str[a] = (char *)malloc(100 * sizeof(char));
}
for (int a = 0; a < num; a++)
{
scanf("%s", str[a]);
}
int a = 0;
while (num - a)
{
str1 = str[a++];
k = strlen(str1);
//将字符串中各字母合数存储在相应位置上
for (int i = 0; i < k; i++)
{
ch[(int)(str1[i] - 'A')]++;
}
//for (int i = 0; i < 26; i++){ printf("%d ", ch[i]); }
int c = 0;
while (k)
{
//首先判断02468
while (ch[25])//ZERO_Z
{
data[c++] = 0; ch[25]--; ch[4]--; ch[17]--; ch[14]--; k = k - 4;
}
while (ch[22])//TWO_W
{
data[c++] = 2; ch[19]--; ch[22]--; ch[14]--; k = k - 3;
}
while (ch[20])//FOUR_U
{
data[c++] = 4; ch[5]--; ch[14]--; ch[20]--; ch[17]--; k = k - 4;
}
while (ch[23])//SIX_X
{
data[c++] = 6; ch[18]--; ch[8]--; ch[23]--; k = k - 3;
}
while (ch[6])//EIGHT_G
{
data[c++] = 8; ch[4]--; ch[8]--; ch[6]--; ch[7]--; ch[19]--; k = k - 5;
}
//再确认以上数字不再出现后,接下来更容易判断
while (ch[14])//ONE_O
{
data[c++] = 1; ch[14]--; ch[13]--; ch[4]--; k = k - 3;
}
while (ch[17])//THREE_R
{
data[c++] = 3; ch[19]--; ch[7]--; ch[17]--; ch[4]--; ch[4]--; k = k - 5;
}
while (ch[5])//FIVE_F
{
data[c++] = 5; ch[5]--; ch[8]--; ch[20]--; ch[4]--; k = k - 4;
}
while (ch[18])//SEVEN_S
{
data[c++] = 7; ch[18]--; ch[4]--; ch[20]--; ch[4]--; ch[13]--; k = k - 5;
}
while (ch[8])//NINE_I
{
data[c++] = 9; ch[13]--; ch[8]--; ch[13]--; ch[4]--; k = k - 4;
}
count = c;
}
//每个数字对应在号码里数字
for (int i = 0; i < count; i++)
{
if (data[i] >= 8)
{
data[i] = data[i] - 8;
}
else data[i] = data[i] + 2;
}
//排序
int temp;
for (int i = 0; i < count - 1; i++)
{
for (int j = 0; j < count - 1 - i; j++)
{
if (data[j] >data[j + 1])
{
temp = data[j + 1];
data[j + 1] = data[j];
data[j] = temp;
}
}
}
for (int i = 0; i < count; i++)
{
printf("%d", data[i]);
}printf("\n");
}
system("pause");
return(0);
}
所学到的东西:
1.利用数组存储26个字母出现的个数。根据某个特有的字母判断是哪一个数字。且当two全都被找出后,two里的‘o’不存在了,就可以用'o'来判断其他数字了。与从前至后删除水王的四个不同ID的算法有异曲同工之妙。
2.关于字符串数组的输入。行数必须确定,每一行字符串的长度可以不确定。malloc在C里真的是万年好用~
3. 输入字符后减‘A’,再用int强制转换,可得该字符在字母表中的位置。