华为上机题汇总(五)

来源:互联网 发布:google 算法面试题 编辑:程序博客网 时间:2024/05/22 00:13

华为上机题汇总(五)

注:编译环境为Visual Studio 2012,答案仅供参考。

目录

  • 华为上机题汇总五
    • 目录
    • 第二十一题
    • 第二十二题
    • 第二十三题
    • 第二十四题
    • 第二十五题

第二十一题

21.通过键盘输入100以内正整数的加、减运算式,请编写一个程序输出运算结果字符串。
输入字符串的格式为:“操作数1 运算符 操作数2”,“操作数”与“运算符”之间以一个空格隔开。

补充说明:
1. 操作数为正整数,不需要考虑计算结果溢出的情况。
2. 若输入算式格式错误,输出结果为“0”。

示例
输入:“4 + 7” 输出:“11”
输入:“4 - 7” 输出:“-3”
输入:“9 ++ 7” 输出:“0” 注:格式错误

#include <iostream>#include <string>#include <vector>using namespace std;bool isNumber(const string &s , int &num){    int sum = 0;    for (auto begin = s.rbegin();begin != s.rend();begin++)    {        if (*begin < '0' || *begin > '9')        {            return false;        }        sum += (*begin - '0') * pow(10,begin - s.rbegin());    }    num = sum;    return true;}int caculate(const string &s){    if (s.empty()) return 0;    auto begin = s.begin();    vector<string> v;    while (begin != s.end())    {        auto ahead = begin + 1;        while (ahead != s.end() && *ahead != ' ')        {            ahead++;        }        string tmp(begin,ahead);        v.push_back(tmp);        if (ahead != s.end()) ahead++;        begin = ahead;    }    if (v.size() != 3) return 0;    int num1,num2;    if (!isNumber(v[0],num1) || !isNumber(v[2],num2) || v[1].size() != 1) return 0;    if (v[1] == "+")    {        return num1 + num2;    }    else if (v[1] == "-")    {        return num1 - num2;    }    return 0;}int main(){    string input;    getline(cin,input);    cout << caculate(input) << endl;    return 0;}

第二十二题

22.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

#include <iostream>#include <string>#include <vector>using namespace std;void convert(const char *ip,vector<int> &v){    const char *begin = ip, *ahead;    while (*begin != '\0')    {        ahead = begin + 1;        while (*ahead != '\0' && *ahead != '.' && *ahead != '/')        {            ahead++;        }        string tmp(begin,ahead);        v.push_back(stoi(tmp));        if (*ahead == '\0') break;        begin = ++ahead;    }}int match(const char *ip, const char *net){    vector<int> vIp;    vector<int> vNet;    convert(ip,vIp);    convert(net,vNet);    for (int i = 0; i < 4; i++)    {        int tmp = vIp[i] & vNet[4+i];        if (tmp != vNet[i])        {            return -1;        }    }    int matchByte = 0;    for (int i = 0; i < 4; i++)    {        if (vIp[i] == vNet[i])        {            matchByte += 8;            continue;        }        int tmp = vIp[i] ^ vNet[i];        int index = 0;        for (int i = 7; i > 0; i--)        {            if (tmp & 1)            {                index = i;            }            tmp >>= 1;        }        matchByte += index;        break;    }    return matchByte;}void max_prefix_match(const char *ip_addr, const char *net_addr_array[], int *n){    int index = 0, maxIndex = -1, maxByte = -1;    while (*net_addr_array != "")    {        int matchByte = match(ip_addr,*net_addr_array++);        if (matchByte > maxByte)        {            maxIndex = index;            maxByte = matchByte;        }        index++;    }    *n = maxIndex;}int main(){    const char * ip_addr = "192.168.1.100";    const char * 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",                               ""};    int n = 0;    max_prefix_match(ip_addr,net_addr_array,&n);    cout << n << endl;    return 0;}

第二十三题

23.编写一个程序,实现排序算法,从小到大输出,数字间以逗号分隔,所有数字为非负整数。数目小于1028;
输入:1,6,3,5
输出:1,3,5,6

#include <iostream>#include <string>#include <vector>#include <algorithm>using namespace std;void sortStr(const string &input, string &output){    vector<int> v;    auto begin = input.begin();    while (begin != input.end())    {        auto ahead = begin + 1;        while (ahead != input.end() && *ahead != ',')        {            ahead++;        }        string tmp(begin,ahead);        v.push_back(stoi(tmp));        if (ahead == input.end()) break;        begin = ++ahead;    }    sort(v.begin(),v.end());    auto vbegin = v.begin();    while (vbegin != v.end())    {        output += to_string(*vbegin++);        if (vbegin != v.end())        {            output.push_back(',');        }    }}int main(){    string input,output;    getline(cin,input);    sortStr(input,output);    cout << output << endl;    return 0;}

第二十四题

24.我们把只包含因子2,3,5的数称为丑数,把1当作第一个丑数,求从小到大的第n个丑数
输入:1都500之间的整数(包含1和500)
输出:第n个丑数。不在1-500输出-1

#include <iostream>#include <vector>using namespace std;int min(int a, int b , int c){    int tmp = a < b ? a : b;    return tmp < c ? tmp : c;}int findArglyNum(int n){    if (n < 1 || n >500)    {        return -1;    }    vector<int> v(n,1);    int pos2 = 0, pos3 = 0, pos5 = 0;    for (int i = 1; i < n; i++)    {        v[i] = min(2*v[pos2],3*v[pos3],5*v[pos5]);        if (v[i] == 2*v[pos2])        {            pos2++;        }        if (v[i] == 3*v[pos3])        {            pos3++;        }        if (v[i] == 5*v[pos5])        {            pos5++;        }    }    return v[n-1];}int main(){    int n;    cin >> n;    cout << findArglyNum(n) << endl;    return 0;}

第二十五题

N个城市(N<=10),从0到9编号,城市间要么有路,要么没路,计算城市A到B之间到底有多少条路。
输入:N A B(1<N<=10,0<=A,B<=9)A为出发城市,B为目的城市。然后n行表示行编号的城市到其他城市有没有路,0表示没有,1表示有路。
输出:A到B有多少条路
输入:3 0 2
1 1 1
1 1 1
1 1 1
输出:2

#include <iostream>#include <vector>using namespace std;bool canVisit(int index, vector<int> hasVisited){    for (auto begin = hasVisited.begin();begin != hasVisited.end();begin++)    {        if (index == *begin)        {            return false;        }    }    return true;}int findWay(int start, int end, int n, vector<int> hasVisited, vector<vector<int>> road){    if (start == end)    {        return 1;    }    int sum = 0;    vector<int> v = road[start];    for (int i = 0; i < n; i++)    {        if (!v[i]) continue;        if (canVisit(i,hasVisited))        {            hasVisited.push_back(i);            sum += findWay(i,end,n,hasVisited,road);        }    }    return sum;}int main(){    int n, a, b;    cin >> n >> a >> b;    vector<vector<int>> road;    for (int i = 0; i < n; i++)    {        vector<int> v;        for (int j = 0; j < n; j++)        {            int x;            cin >> x;            v.push_back(x);        }        road.push_back(v);    }    vector<int> hasVisited;    hasVisited.push_back(a);    cout << findWay(a,b,n,hasVisited,road) << endl;    return 0;}
1 0
原创粉丝点击