牛客华为机试题刷题笔记(四)

来源:互联网 发布:java web前后端交互 编辑:程序博客网 时间:2024/06/05 03:40

代码见github


单词倒排

没啥好说的,就是要对原字符串预处理一下。

#include <iostream>#include <string>#include <sstream>#include <vector>using namespace std;int main(){    string str;    while(getline(cin,str))    {    for(int i=0;i<str.size();++i)    {        if(!(std::isalpha(str[i])||str[i]==' '))        {        str[i]=' ';        }    }    stringstream ss(str);    string w;    vector<string>v;    while(ss>>w)    {        v.push_back(string(w.rbegin(),w.rend()));    }    string tmp;    for(int i=0;i<v.size();++i)    {        tmp+=v[i];        tmp+=" ";    }    tmp.pop_back();    string res(tmp.rbegin(),tmp.rend());    cout<<res<<endl;    }    return 0;}

字符串运用-密码截取

最长回文子串,有很多方法,我的方法比较蠢。
求出回文子串,然后比较长度。

求回文子串的方法有很多,比较高效的是从中间往左右扩散。

#include <iostream>#include <string>using namespace std;string subPalindrome(string s, int left, int right){    int strLen = s.length();    while (left >= 0 && right<strLen && s[left] == s[right])    {        left--;        right++;    }    left++;    right--;    return s.substr(left, right - left + 1);}int main(){    string str;    while (cin >> str)    {        int mm = 0;        int n = str.size();        for (int i = 0; i < n; ++i)        {            string sub1 = subPalindrome(str, i, i);            int l = sub1.size();            if (l > mm)                mm = l;            string sub2 = subPalindrome(str, i, i + 1);            int r = sub2.size();            if (r > mm)                mm = r;        }        cout << mm << endl;    }    return 0;}

整数与IP地址间的转换

这个就是socket编程的运用了,注意大小端存储即可,

#include <iostream>#include <string>#include <sys/socket.h>#include <netinet/in.h>#include<arpa/inet.h>using namespace std;unsigned long Ip2Num(string ip){    struct sockaddr_in addr;    inet_pton(AF_INET,ip.c_str(),(void*)&addr.sin_addr);    unsigned long rs=addr.sin_addr.s_addr;    rs=htonl(rs);    return rs;}string Num2Ip(unsigned long num){    struct sockaddr_in addr;    addr.sin_addr.s_addr=ntohl(num);    char buff[16];    inet_ntop(AF_INET,(void*)&addr.sin_addr,buff,16);    string ss(buff);    return ss;}int main(){    string ip;    unsigned int num;    while(cin>>ip>>num)    {        unsigned long r1=Ip2Num(ip);        string r2=Num2Ip(num);        cout<<r1<<endl<<r2<<endl;    }}

图片整理

std::sort即可

#include <iostream>#include <algorithm>using namespace std;int main(){    string str;    while(getline(cin,str))    {        sort(str.begin(),str.end());        cout<<str<<endl;    }    return 0;}

蛇形矩阵

有意思的题,把高中算数列的本事都拿出来了,最后算出一个公式,直接赋值即可。v[i][j]=(j+3+2i)j/2+(i+1)i/2+1

#include <iostream>#include <vector>using namespace std;int main(){    int n;    while (cin >> n)    {        vector<vector<int>>v(n, vector<int>(n));        for (int i = 0; i < n; ++i)        {            for (int j = 0; j < n - i; ++j)            {                v[i][j]=(j + 3 + 2 * i)*j / 2 + (i + 1)*i / 2 + 1;            }        }        for (int i = 0; i < n; ++i)        {            for (int j = 0; j < n - i; ++j)            {                if(j==0)                {                    cout<<v[i][j];                    continue;                }                cout <<" "<< v[i][j];            }            cout << endl;        }    }}

字符串加密

加密其实就是对字符进行hash,具体操作就是key要去掉重复字符,并且不改变原字符在key中的序列,比如ACCD,变成ACD。

hash的过程,是将上述key按顺序排列在26个字母之下,一一对应:
[ABC]DEFGHI…..Z
[ACD]BEFG……..

不足的地方补齐,且不重复出现,这样就出现了一个一一对应关系,例如:

明文是D,密文是B等等。

理解题意之后就很简单了,注意大小写处理:

#include <iostream>#include <string>#include <vector>#include <unordered_map>#include <algorithm>using namespace std;int main(){    string key;    string str;    //char m[26];    while (getline(cin,key))    {        getline(cin, str);        int m[26] = { 0 };        string dict;        for (int i = 0; i < key.size(); ++i)        {            if (m[tolower(key[i]) - 'a'] == 0)            {                dict += tolower(key[i]);                m[tolower(key[i]) - 'a'] = 1;            }        }        for (int i = 0; i < 26; ++i)        {            if (m[i] == 0)            {                dict += 'a' + i;            }        }    //  cout << dict << endl;        for (int i = 0; i < str.size(); ++i)        {            if (!isalpha(str[i]))                continue;            bool islower = true;            if (str[i] <= 'Z'&&str[i] >= 'A')                islower = false;            str[i] = dict[tolower(str[i]) - 'a'];            if (!islower)                str[i] = toupper(str[i]);        }        cout << str << endl;    }    return 0;}

统计每个月兔子个数

斐波拉切数列的应用

#include <iostream>#include <vector>using namespace std;int main(){    int n;    while(cin>>n)    {        if(n==1)            cout<<1<<endl;        else if(n==2)            cout<<1<<endl;        else if(n==3)            cout<<2<<endl;        else        {            vector<int>a(n+1);            a[1]=1;            a[2]=1;            a[3]=2;            for(int i=4;i<=n;i++)            {                a[i]=a[i-1]+a[i-2];            }            cout<<a[n]<<endl;        }    }    return 0;}

求小球落地5次后所经历的路程和第5次反弹

数学题,画个图计算一下即可。

#include <iostream>#include <cmath>using namespace std;int main(){    int n;    while (cin >> n)    {        double r1 = n;        for (int i = 0; i < 4; ++i)        {            r1 += static_cast<double>(n) / (pow(2,i));        }        double r2 = n*pow(0.5, 5);        cout << r1 << endl << r2 << endl;    }    return 0;}

判断两个IP是否属于同一子网

[这题未通过]但柑橘题目的输入应该是有问题的。我的思路还是要利用socket函数,算出掩码和IP,这样在同一子网下的两个ip与上掩码的值是相等的。

#include<iostream>#include<sys/socket.h>#include <netinet/in.h>#include<arpa/inet.h>#include <sstream>using namespace std;int main(){    string mask;    string ip1;    string ip2;    while(cin>>mask>>ip1>>ip2)    {        unsigned long maskNum=0;        unsigned long ip1Num=0;        unsigned long ip2Num=0;        struct sockaddr_in addr;        int ret;        ret = inet_pton(AF_INET,mask.c_str(),(void*)&addr.sin_addr);        if(ret!=1)        {            cout<<1<<endl;            continue;        }           ret = inet_pton(AF_INET,ip1.c_str(),(void*)&addr.sin_addr);        if(ret!=1)        {            cout<<1<<endl;            continue;        }           ret = inet_pton(AF_INET,ip2.c_str(),(void*)&addr.sin_addr);         if(ret!=1)        {            cout<<1<<endl;            continue;        }        maskNum=htonl(addr.sin_addr.s_addr);        ip1Num=htonl(addr.sin_addr.s_addr);        ip2Num=htonl(addr.sin_addr.s_addr);        if((maskNum&ip1Num)==(maskNum&ip2Num))            cout<<0<<endl;        else            cout<<2<<endl;        //cout <<((maskNum&ip1Num)==(maskNum&ip2Num))<<endl;    }}

统计英文、空格、数字、其他字符

没啥好说。

#include <iostream>#include <string>using namespace std;int main(){    string str;    while(getline(cin,str))    {        int alpha=0;        int digit=0;        int other=0;        int space=0;        for(int i=0;i<str.size();++i)        {            if(str[i]==' ')                space++;            else if(std::isalpha(str[i]))                alpha++;            else if(std::isdigit(str[i]))                digit++;            else                other++;        }        cout<<alpha<<endl;        cout<<space<<endl;        cout<<digit<<endl;        cout<<other<<endl;    }}
原创粉丝点击