整理的华为招聘机试题

一,通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。
比如字符串“abacacde”过滤结果为“abcde”。
 
要求实现函数: 
void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr);
 
【输入】 pInputStr:  输入字符串
         lInputLen:  输入字符串长度         
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
 
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
 
示例 
输入:“deefd”        输出:“def”
输入:“afafafaf”     输出:“af”
输入:“pppppppp”     输出:“p”
 
#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;
}
View Code

注:程序中使用计数排序,使程序闲的简单

 

二,通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。

压缩规则:
1. 仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc".
2. 压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"
 
要求实现函数: 
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
 
【输入】 pInputStr:  输入字符串
         lInputLen:  输入字符串长度         
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
 
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
 
示例 
输入:“cccddecc”   输出:“3c2de2c”
输入:“adef”     输出:“adef”
输入:“pppppppp” 输出:“8p”
 
#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;
}
View Code

 三,通过键盘输入100以内正整数的加、减运算式,请编写一个程序输出运算结果字符串。

输入字符串的格式为:“操作数1 运算符 操作数2”,“操作数”与“运算符”之间以一个空格隔开。
 
补充说明:
1. 操作数为正整数,不需要考虑计算结果溢出的情况。
2. 若输入算式格式错误,输出结果为“0”。
 
要求实现函数: 
void arithmetic(const char *pInputStr, long lInputLen, char *pOutputStr);
 
【输入】 pInputStr:  输入字符串
         lInputLen:  输入字符串长度         
【输出】 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
 
【注意】只需要完成该函数功能算法,中间不需要有任何IO的输入输出
 
示例 
输入:“4 + 7”  输出:“11”
输入:“4 - 7”  输出:“-3”
输入:“9 ++ 7”  输出:“0” 注:格式错误
#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;
}
View Code

四,手机号码合法性判断(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;
}
View Code

五,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

posted on 2013-09-14 21:38  张三的哥哥  阅读(2347)  评论(0编辑  收藏  举报