[C/C++]2014年7月华为校招机试真题(一)
同学昨天去参加华为软件机试,一共三道题,难度依次递增,两个小时。第一题普遍很简单,基本都能写出来,第二题难度适中,相对费些时间,第三题一般情况下就不是我等非软件专业在规定时间内能驾驭的了的啦。废话不多说,发几道我同学记下的题,还有我自己敲的代码。
第一题(60分):
按要求分解字符串,输入两个数M,N;M代表输入的M串字符串,N代表输出的每串字符串的位数,不够补0。例如:输入2,8, “abc” ,“123456789”,则输出为“abc00000”,“12345678“,”90000000”
我写的代码如下:
- #include <iostream>
- void cut(int n,const char *input);
- int main()
- {
- char str[20][20] = {"abc","1234567890"};
- int n = 8; //设置截取长度
- int m = 2; //设置字符串个数
- for (int i = 0; i < m; i++) {
- cut(n,str[i]);
- }
- return 0;
- }
- void cut(int n,const char *input){
- char temp[100][100];
- int i = 0,j = 0,k = 0;
- if (strlen(input) <= n) //若字符串长度小于或者等于要求截取长度
- { //则依次将输入的字符串中的字符放入临时二维数组temp的第一行
- for (i = 0; i < n; i ++) //并将大于n的地方补0
- {
- if (input[i] != '\0')
- {
- temp[j][k ++] = input[i];
- }else
- {
- temp[j][k++] = '0';
- }
- }
- }else //若字符串长度大于要求截取长度
- { //则当列数没到达n时,依次将输入中的字符放入temp第一行
- for (i = 0; i < strlen(input); i++)
- {
- if ((i + 1) % n != 0)
- {
- temp[j][k++] = input[i];
- }else
- {
- temp[j][k++] = input[i]; //当列数到达n时,依次将输入中的字符放入temp的下一行
- k = 0;
- j++;
- }
- }
- while (k < n)
- {
- temp[j][k++] = '0'; //将最后一行剩下的元素补0
- }
- }
- for (i = 0; i <=j; i++) {
- temp[i][k] = '\0'; //给每一行末尾添加空字符
- }
- for (i = 0; i <=j; i++) {
- std::cout << temp[i] <<'\n'; //依次输出结果
- }
- }
还是一道第一题,我另一个同学记得
第一题:拼音转数字
输入是一个只包含拼音的字符串,请输出对应的数字序列。转换关系如下:
描述: 拼音 yi er san si wu liu qi ba jiu
阿拉伯数字 1 2 3 4 5 6 7 8 9
输入字符只包含小写字母,所有字符都可以正好匹配
运行时间限制:无限制
内存限制: 无限制
输入: 一行字符串,长度小于1000
输出: 一行字符(数字)串
样例输入: yiersansi
样例输出: 1234
- #include <iostream>
- void numTrans(const char *input,char *output);
- int main(int argc, const char * argv[])
- {
- char pinYinShuZi[1000] = "yiersansiwuliuqibajiu";
- char shuZi[100];
- numTrans(pinYinShuZi, shuZi);
- std::cout << pinYinShuZi << std::endl;
- std::cout << shuZi << std::endl;
- return 0;
- }
- void numTrans(const char *input,char *output)
- {
- char temp[100]; //用于临时保存转换出的阿拉伯数字
- int i = 0,j = 0;
- for (i = 0; i < strlen(input); i++) {
- switch (input[i]) { //遍历字符串,分别将拼音转换成阿拉伯数字,并放入temp数组
- case 'y':
- i++;
- temp[j++] = '1';
- break;
- case 'e':
- i++;
- temp[j++] = '2';
- break;
- case 's':
- if (input[i + 1] == 'a') {
- i++;
- i++;
- temp[j++] = '3';
- }else{
- i++;
- temp[j++] = '4';
- }
- break;
- case 'w':
- i++;
- temp[j++] = '5';
- break;
- case 'l':
- i++;
- i++;
- temp[j++] = '6';
- break;
- case 'q':
- i++;
- temp[j++] = '7';
- break;
- case 'b':
- i++;
- temp[j++] = '8';
- break;
- case 'j':
- i++;
- i++;
- temp[j++] = '9';
- break;
- default:
- break;
- }
- }
- temp[j] = '\0'; //给数字数组末尾添加空字符
- for (i = 0; i <= j; i++) {
- output[i] = temp[i]; //把临时数组赋给输出字符串
- }
- }
第二题:去除重复字符并排序
运行时间限制:无限制
内容限制: 无限制
输入: 字符串
输出: 去除重复字符并排序的字符串
样例输入: aabcdefff
样例输出: abcdef
因为此题我没看懂是去除输入里的所有相同字符,还是仅去除相邻的有重复的字符,所以在代码里两种方法都写了,其中一种方法被我注释了
- #include <iostream>
- void transAndSort(const char * input,char * output);
- int main(int argc, const char * argv[])
- {
- char str[100] = "aabcdefffa";
- char res[100];
- transAndSort(str,res);
- std::cout << str << std::endl;
- std::cout << res << std::endl;
- return 0;
- }
- void transAndSort(const char * input,char * output)
- {
- int i = 0,j = 1,n,m;
- int flag = 0;
- char temp[100];
- char ex;
- temp[0] = input[0];
- // for (i = 1; i < strlen(input); i++) { //去除重复的字符
- // if (input[i - 1] != input[i]) { //仅保存与前一个字符不相等的字符
- // temp[j++] = input[i]; //此处是去除几个相邻的重复的字符的方法
- // }
- // }
- for (i = 1; i < strlen(input); i++) { //此代码块去除字符串中所有有重复的字符
- for (m = 0; m < j; m++) { //依次将input中的字符与temp中的所有字符比较
- if (temp[m] == input[i]) { //若有相同则舍去
- flag = 1;
- }
- }
- if (flag != 1) { //flag置1则说明现input的字符与temp中的字符有重复
- temp[j++] = input[i];
- }else
- flag = 0;
- }
- temp[j] = '\0'; //这时j等于strlen(temp)
- for (i = 0; i < j - 1; i++)
- for (n = 0;n < j - 1 - i;n++)
- {
- if (temp[n] > temp[n + 1]) {
- ex = temp[n];
- temp[n] = temp[n + 1];
- temp[n + 1] = ex;
- }
- }
- for (i = 0; i <= j; i++) {
- output[i] = temp[i];
- }
- }
第三题:等式变换
输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立。
1 2 3 4 5 6 7 8 9 = X
比如:
12-34+5-67+89 = 5
1+23+4-5+6-7-8-9 = 5
请编写程序,统计满足输入整数的所有整数个数。
输入: 正整数,等式右边的数字
输出: 使该等式成立的个数
样例输入:5
样例输出:21(此处经大家提醒已更正)
这道题有一定难度,在下暂时还没有搞定,大家有什么想法可以一起讨论下!
去吃饭了,明天就周一了,大家珍惜今天晚上的自由时光吧
[C/C++]2014年7月华为校招机试真题(二)
今天收到通知12号上午9点半去参加华为机试,由于最近一直忙论文的事,就没空复习C++,也就没写博客,今天同学给了几道前几天的题,自己做了下,就拿出来给大家分享分享。
前两道不难,很容易做出来,第三道对于非软件专业的同学来说就不那么容易了。
建议大家最好把链表也稍微看下,据说这次考试有同学的第二题考到了约瑟夫环。
说句题外话,最近在看《代码整洁之道》,英文叫clean code这本书,受益挺多的,大家有兴趣可以看一下(示例代码是用Java写的),对今后想要从事软件行业的同学来说还是非常有帮助的。
回到正题,题目及我写的代码如下:
第一题:
大意如下:1,2,3。。。n展灯,同时有n个人,
第1个人将1的倍数的灯拉一下,
第2个人将2的倍数的灯拉一下,
问最后有几展灯是亮的,
初始状态灯是灭的,
输入整数n(n<65536)
输出亮的灯数
- int main()
- {
- int n;
- int i,j;
- int sum = 0;
- std::cin >> n;
- std::cin.get();
- bool lightBulb[65536] = {0};
- for(i = 1;i <= n;i++) //通过两嵌套循环模拟N个人一次拉灯
- {
- for(j = 1;j <= n;j++)
- {
- if( j % i == 0 )
- {
- lightBulb[j - 1] = !lightBulb[j - 1]; //!为取非,~为按位取反
- }
- }
- }
- for(j = 0;j < n;j++)
- {
- if(lightBulb[j] != 0) //统计灯泡亮着的个数
- sum++;
- }
- std::cout << sum;
- sum = 0;
- system("pause");
- return 0;
- }
第二题:
输入整数(n是小于9位数的整数),当作字符串处理,
看是否有相同的子串,如1212,相同子串是12,
141516则没有子串(子串长度必须大于等于2)。
若有相同子串则输出1,否则输出0
输入:长度小于9的整数
输出1或者0
- #include <iostream>
- int main()
- {
- char input[10];
- int i = 0,j;
- int res = 0;
- std::cin >> input;
- for(i = 2;i < (strlen(input) - 1);i++) //一个嵌套循环来检查是否有子串
- {
- for(j = i - 1;j >=0;j--) //依次将字符与前面的字符比较,若相等则分别将这两个字符的下一个字符取出来进行比较
- { //相等则说明至少有一个两个字符的子串
- if(input[i] == input[j] &&
- input[i + 1] == input[j + 1])
- {
- res = 1; //有子串时,将结果置一
- break;
- }
- }
- if(res == 1)
- break;
- }
- std::cout << res; //输出结果
- system("pause");
- return 0;
- }
第三题:
大意如下:
输入整数m【视作分子】,整数n【视作分母】(m<n),
输出小数形式,若是无穷小数保留小数部分100的长度,
若小数部分循环则写成如下形式 比如1/3=0.(3)
这道题对博主来说相当有挑战性的,目前还没搞定,搞定了给大家po上来
练习的几道华为往年的机试题,都不难,贴出来和大家分享下!机试只要对一道就可以通过,所以今年参加华为机试的同学压力不要太大
1、手机号码合法性判断(20分)
问题描述:我国大陆运营商的手机号码标准格式为:
国家码+手机号码,例如:8613912345678。
特点如下:
1、 长度13位;
2、 以86的国家码打头;
3、 手机号码的每一位都是数字。请实现手机号码合法性判断的函数
(注:考生无需关注手机号码的真实性,
也就是说诸如86123123456789这样的手机号码,我们也认为是合法的),
要求:1) 如果手机号码合法,返回0;
2) 如果手机号码长度不合法,返回1;
3) 如果手机号码中包含非数字的字符,返回2;
4) 如果手机号码不是以86打头的,返回3;
【注】除成功的情况外,以上其他合法性判断的优先级依次降低。也就是说,
如果判断出长度不合法,直接返回1即可,不需要再做其他合法性判断。
要求实现函数:
int verifyMsisdn(char* inMsisdn)
【输入】 char* inMsisdn,表示输入的手机号码字符串。
【输出】 无
【返回】 判断的结果,类型为int。
示例输入: inMsisdn = “86912345678“ 输出: 无 返回: 1
输入: inMsisdn = “8813912345678“ 输出: 无 返回: 3
输入: inMsisdn = “8613912345678“ 输出: 无 返回: 0
第一题很简单,几个if语句就能搞定
- #include <iostream>
- int verifyMsisdn(char* inMsisdn);
- int main()
- {
- //char num[20]= "869123456789"; //返回1
- //char num[20]= "8813912345678"; //返回3
- //char num[20]= "8613912345678"; //返回0
- char num[20]= "869123456+_78"; //返回2
- int res = verifyMsisdn(num);
- std::cout << res;
- system("pause");
- return 0;
- }
- int verifyMsisdn(char* inMsisdn)
- {
- int i = 0;
- if(strlen(inMsisdn) != 13) //检查手机号长度是否为13,
- return 1; //若不是,返回1
- // std::cout << strlen(inMsisdn) << std::endl;
- if(inMsisdn[0] != '8' && inMsisdn[1] != '6') //检查前两位是否为86
- return 3; //若不是,返回3
- for(i = 0; i < 13;i++) //检查号码是否有非数字字符
- {
- if(inMsisdn[i] >= '0' && inMsisdn[9] <= '9')
- {
- return 0; //若没有,返回0
- }else
- return 2; //若有,返回2
- }
- }
第二题也很简单,涉及到了排序,我使用了冒泡排序方法
2. 将一个字符串的元音字母复制到另一个字符串,并排序(30分)
问题描述:有一字符串,里面可能包含英文字母(大写、小写)、数字、特殊字符,现在需要实现一函数,
将此字符串中的元音字母挑选出来,存入另一个字符串中,并对字符串中的字母进行从小到大的排序。
(小写的元音字母在前,大写的元音字母在后,依次有序)。
说明: 1、 元音字母是a,e,i,o,u,A,E,I,O,U。
2、 筛选出来的元音字母,不需要剔重;最终输出的字符串,小写元音字母排在前面,大写元音字母排在后面,依次有序。
要求实现函数:
void sortVowel (char* input, char* output);
【输入】 char* input,表示输入的字符串
【输出】 char* output,排好序之后的元音字符串。
【返回】 无
示例
输入:char *input = “Abort!May Be Some Errors In Out System. “
输出:char *output =“aeeeoooAEIO “
- #include <iostream>
- void sortVowel (char* input, char* output);
- int main()
- {
- char arr[] = "Abort!May Be Some Errors In Out System. ";
- char out[100];
- sortVowel (arr, out);
- std::cout << arr << '\n' << out << std::endl;
- system("pause");
- return 0;
- }
- void sortVowel (char* input, char* output)
- {
- int i = 0,j = 0,k = 0;
- char up[100]; //存放大写元音字母
- char low[200]; //存放小写元音字母
- for(i = 0;i < strlen(input);i++)
- {
- if(input[i] >= 'a' && input[i] <= 'z') //若字符为小写字母
- {
- switch(input[i]) //则找出小写元音字母并放入low数组
- {
- case 'a': low[j++] = input[i];
- break;
- case 'e': low[j++] = input[i];
- break;
- case 'i': low[j++] = input[i];
- break;
- case 'o': low[j++] = input[i];
- break;
- case 'u': low[j++] = input[i];
- break;
- default:
- break;
- }
- }else if(input[i] >= 'A' && input[i] <= 'Z') //若字符为大写字母
- {
- switch(input[i]) //则找出大写元音字母并放入up数组
- {
- case 'A': up[k++] = input[i];
- break;
- case 'E': up[k++] = input[i];
- break;
- case 'I': up[k++] = input[i];
- break;
- case 'O': up[k++] = input[i];
- break;
- case 'U': up[k++] = input[i];
- break;
- default:
- break;
- }
- }
- }
- low[j] = '\0'; //分别给两个数组末尾添加空字符
- up[k] = '\0';
- int n = 0;
- char temp;
- for(i = 1;i < j;i++) //对小写元音字母进行从小到大排序
- for(n = 0;n < j - 1;n++)
- {
- if(low[n] > low[n + 1])
- {
- temp = low[n];
- low[n] = low[n + 1];
- low[n + 1] = temp;
- }
- }
- for(i = 1;i < k;i++) //对大写元音字母进行从小到大排序
- for(n = 0;n < k - 1;n++)
- {
- if(up[n] > up[n + 1])
- {
- temp = up[n];
- up[n] = up[n + 1];
- up[n+1] = temp;
- }
- }
- strcat(low,up); //将up的字符串添加到low的末尾
- for(i = 0;i < strlen(low) + 1;i++) //将处理好的字符串赋予output
- output[i] = low[i];
- }