整理的华为招聘机试题
#include <iostream> using namespace std; const int N = 300; int main() { char pInputStr[N], pOutputStr[N]; long lInputLen, j = 0; cin>>pInputStr; lInputLen = strlen(pInputStr); bool flag[26] = {false}; for (long i = 0; i < lInputLen; i++){ if (!flag[pInputStr[i] - 'a']){ flag[pInputStr[i] - 'a'] = true; pOutputStr[j++] = pInputStr[i]; } } pOutputStr[j] = '\0'; cout<<pOutputStr<<endl; return 0; }
注:程序中使用计数排序,使程序闲的简单
二,通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。
#include <iostream> using namespace std; const int N = 300, M = 100; int main() { char pInputStr[N], pOutputStr[N]; long lInputLen, j = 0, flag = 0; cin>>pInputStr; lInputLen = strlen(pInputStr); for (long i = 0; i < lInputLen - 1; i++){ if (pInputStr[i] == pInputStr[i + 1]){ flag = 1; while (pInputStr[i] == pInputStr[i + flag] && i + flag <= lInputLen - 1){ flag++; } char tmpCh[M]; int k = 0, tmp = flag; while (tmp) { tmpCh[k++] = (tmp % 10) + '0'; tmp = tmp / 10; } tmpCh[k--] = '\0'; while (k >= 0) { pOutputStr[j++] = tmpCh[k--]; } pOutputStr[j++] = pInputStr[i]; pOutputStr[j] = '\0'; i = i + flag - 1; }else{ flag = 0; pOutputStr[j++] = pInputStr[i]; } } if (flag == 0){ pOutputStr[j++] = pInputStr[lInputLen - 1]; } pOutputStr[j] = '\0'; cout<<pOutputStr<<endl; return 0; }
三,通过键盘输入100以内正整数的加、减运算式,请编写一个程序输出运算结果字符串。
#include <iostream> #include <cstring> using namespace std; const int N = 100, M = 30; int getNum(char *p, int len) { int tmp = 0; for (int i = 0; i < len; i++){ tmp = tmp * 10 + (p[i] - '0'); } return tmp; } int main() { char pInputStr[N], operation[M]; int num1, num2, num; cin.getline(pInputStr, N, '\n'); char *p = strtok(pInputStr, " "); if (p){ num1 = getNum(p, strlen(p)); }else{ num = 0; } p = strtok(NULL, " "); if (p){ strcpy(operation, p); operation[strlen(p)] = '\0'; }else{ num = 0; } p = strtok(NULL, " "); if (p){ num2 = getNum(p, strlen(p)); }else{ num = 0; } if (strcmp(operation, "+") == 0){ num = num1 + num2; }else if (strcmp(operation, "-") == 0){ num = num1 - num2; }else{ num = 0; } cout << num <<endl; return 0; }
四,手机号码合法性判断(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 = “869123456789“
输出: 无
返回: 1
输入: inMsisdn = “8813912345679“
输出: 无
返回: 3
输入: inMsisdn = “86139123456789“
输出: 无
返回: 0
#include <iostream> #include <cstring> using namespace std; const int N = 30; bool getWord(char *pInputStr) { bool b =false; for (int i = 0; i < 13; i++){ if (!(pInputStr[i] >= '0' && pInputStr[i] <= '9')){ b = true; break; } } return b; } int main() { char pInputStr[N]; int flag = 0; cin >> pInputStr; if (strlen(pInputStr) != 13){ flag = 1; }else if (getWord(pInputStr)){ flag = 2; }else if (pInputStr[0] != '8' || pInputStr[1] != '6'){ flag = 3; } cout<<flag<<endl; return 0; }
五,IP地址匹配(60分)
问题描述:
在路由器中,一般来说转发模块采用最大前缀匹配原则进行目的端口查找,具体如下:
IP地址和子网地址匹配:
IP地址和子网地址所带掩码做AND运算后,得到的值与子网地址相同,则该IP地址与该子网匹配。
比如:
IP地址:192.168.1.100
子网:192.168.1.0/255.255.255.0,其中192.168.1.0是子网地址,255.255.255.0是子网掩码。
192.168.1.100&255.255.255.0 = 192.168.1.0,则该IP和子网192.168.1.0匹配
IP地址:192.168.1.100
子网:192.168.1.128/255.255.255.192
192.168.1.100&255.255.255.192 = 192.168.1.64,则该IP和子网192.168.1.128不匹配
最大前缀匹配:
任何一个IPv4地址都可以看作一个32bit的二进制数,比如192.168.1.100可以表示为:11000000.10101000.00000001.01100100,
192.168.1.0可以表示为11000000.10101000.00000001.00000000
最大前缀匹配要求IP地址同子网地址匹配的基础上,二进制位从左到右完全匹配的位数尽量多(从左到右子网地址最长)。比如:
IP地址192.168.1.100,同时匹配子网192.168.1.0/255.255.255.0和子网192.168.1.64/255.255.255.192,
但对于子网192.168.1.64/255.255.255.192,匹配位数达到26位,多于子网192.168.1.0/255.255.255.0的24位,
因此192.168.1.100最大前缀匹配子网是192.168.1.64/255.255.255.192。
请编程实现上述最大前缀匹配算法。
要求实现函数:
void max_prefix_match(const char *ip_addr, const char *net_addr_array[], int
*n)
【输入】ip_addr:IP地址字符串,严格保证是合法IPv4地址形式的字符串
net_addr_array:子网地址列表,每一个字符串代表一个子网,包括子网地址和掩码,
表现形式如上述,子网地址和子网掩码用’/’分开,严格保证是
合法形式的字符串;如果读到空字符串,表示子网地址列表结束
【输出】n:最大前缀匹配子网在*net_addr_array[]数组中对应的下标值。如果没有匹配返回-1
示例
输入:
ip_addr = "192.168.1.100"
net_addr_array[] =
{
"192.168.1.128/255.255.255.192",
"192.168.1.0/255.255.255.0",
"192.168.1.64/255.255.255.192",
"0.0.0.0/0.0.0.0",
""
}
输出:n = 2
strtok
strtok_r