企业编程题实战(三)

1、名字的漂亮度

给出一个名字,该名字有26个字符串组成,定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。每个字母都有一个“漂亮度”,范围在1到26之间。没有任何两个字母拥有相同的“漂亮度”。字母忽略大小写。给出多个名字,计算每个名字最大可能的“漂亮度”。
收获sort函数不能对map进行操作
map的排序默认按照key从小到大进行排序,若要按照其他规则进行排序:
1、按照key从大到小进行排序

map<string, int, greater<string> > mapStudent;

2、 重定义map内部的Compare函数,按照键字符串长度大小进行排序

struct CmpByKeyLength {  
  bool operator()(const string& k1, const string& k2) {  
    return k1.length() < k2.length();  
  }  
};
map<string, int, CmpByKeyLength > mapStudent;

3、key是结构体的排序


typedef struct tagStudentInfo  
{  
    int iID;  
    string  strName;  
    bool operator < (tagStudentInfo const& r) const {  
        //这个函数指定排序策略,按iID排序,如果iID相等的话,按strName排序  
        if(iID < r.iID)  return true;  
        if(iID == r.iID) return strName.compare(r.strName) < 0;  
        return false;
    }  
}StudentInfo;//学生信息

4、将map按value排序


bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {  
  return lhs.second < rhs.second;  
}  
struct CmpByValue {  
  bool operator()(const PAIR& lhs, const PAIR& rhs) {  
    return lhs.second < rhs.second;  
  }  
};

  /*把map中元素转存到vector中*/   
  vector<PAIR> name_score_vec(name_score_map.begin(), name_score_map.end());  
  sort(name_score_vec.begin(), name_score_vec.end(), CmpByValue());  
  /*sort(name_score_vec.begin(), name_score_vec.end(), cmp_by_value);也是可以的*/
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
using namespace std;

int main() {
    int N;
    while (cin >> N) {
        for (int i = 0; i < N; i++) {
            string temp;
            cin >> temp;
            map<char, int> strs;
            for (int i = 0; i < temp.size(); i++) {
                if (strs.count(temp[i]) == 0)
                    strs[temp[i]] = 1;
                else strs[temp[i]]++;
            }
            vector<pair<char, int>> vectorMap;
            for (auto &it:strs) {
                vectorMap.emplace_back(it);
            }
            sort(vectorMap.begin(), vectorMap.end(), [](const pair<char,int>& a, const pair<char, int>& b)->bool {
                if (a.second == b.second) return a.first < b.first;
                else return a.second > b.second;
                });
            int sum = 0;
            int value = 26;
            for (auto& it : vectorMap) {
                sum += it.second * value;
                value--;
            }
            cout << sum << endl;
        }
    }
    return 0;
}
2、按字节截取字符串

编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输入"我ABC汉DEF"6,应该输出为"我ABC"而不是"我ABC+汉的半个"。
收获
1、string本身就会判断最后一个字节是否为多余的半个汉字,是的话不输出该字节。
2、汉字占两个字节,每个字节的ASCII码最高位均为1,由于char默认为带符号类型,所以汉字的ASCII码小于0,而英文数字等其他字符占一个字节,ASCII码最高位为0,值在0~127之间。因此,只需要判断该字节是否小于0就能推断出是否为半个汉字。再向前推算有连续几个半个汉字,若有偶数个,则输出最后半个汉字,否则不输出。
1、

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string str;
    int num;
    while (cin >> str >> num)
    {
        cout << str.substr(0, num) << endl;
    }
    return 0;
}

2、

#include<iostream>
#include<string>
using namespace std;
int main(){
    string str;
    int num;
    while(cin>>str>>num){
        int temp=num-1;
        while(temp>=0&&str[temp]<0)
            temp--;
        if((num-temp)%2==0) num--;
        cout<<str.substr(0,num)<<endl;
    }
    return 0;
}
3、四则运算

请实现如下接口
/* 功能:四则运算

  • 输入:strExpression:字符串格式的算术表达式,如: “3+2*{1+2*[-4/(8-6)+7]}”
  • 返回:算术表达式的计算结果
    /
    public static int calculate(String strExpression)
    {/
    请实现*/
    return 0;
    }
    约束:pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。pucExpression算术表达式的有效性由调用者保证;
    1、中缀表达式转后缀表达式
    中缀表达式9+(3−1)∗3+10/2转化为后缀表达式为931−3∗+102/+.
    规则:从左到右遍历中缀表达式的每一数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈 顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。
    a.初始化一空栈,用来对符号进出栈使用。
    b.第一个字符是数字9,输出9,后面是符号“+”,进栈。
    c.第三个字符是“(”,依然是符号,因其只是左括号,还没有配对,故进栈。
    d.第四个字符是数字3,输出,总表达式为9 3,接着是“-”,进栈。
    e.接下来是数字1,输出,总表达式为9 3 1,后面是符号“)”,此时,我们需要去匹配此前的“(”,所以栈顶依次出栈,并输出,直到“(”出栈为止。此时左括号上方只有“-”,因此输出“-”。总的表达式为9 3 1 -。
    f.接着是数字3,输出,总的表达式为9 3 1 - 3.紧接着是符号“
    ”,因为此时的栈顶符号为“+”号,优先级低于“”,因此不输出,“”进栈。
    g.之后是符号“+”,此时当前栈顶元素“”比这个“+”的优先级高,因此栈中元素出栈并输出(没有比“+”更低的优先级,所以全部出栈),总输出表达式为9 3 1 - 3 * +。然后将当前这个符号“+”进栈。
    h.紧接着数字10,输出,总表达式为9 3 1 - 3 * + 10。后是符号“/”,所以“/”进栈。
    i.最后一个数字2,输出,总的表达式为9 3 1 - 3 * + 10 2。
    j.因已经到最后,所以将栈中符号全部出栈并输出。最终输出的后缀表达式结果为9 3 1 - 3 * + 10 2 / +。
    2、后缀表达式计算结果(栈的应用)
    后缀表达式为:931−3∗+102/+
    规则为:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
    a.初始化一个空栈。此栈用来对要运算的数字进行进出使用。
    b.后缀表达式中前三个是、都是数字,所以9 3 1 进栈。
    c.接下来是“-”,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再讲2进栈。
    d.接着是数字3进栈。
    e.后面是“
    ”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。
    f.下面是“+”,所以栈中6和9出栈,9和6相加,得到15,将15进栈。
    g.接着是10和2两数字进栈。
    h.接下来是符号“/”,因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈。
    i.最后一个是符号“+”,所以15与5出栈并相加,得到20,讲20进栈。
    j.结果是20出栈,栈变为空。
4、找出字符串中第一个只出现一次的字符

收获:第一次调试未过的例子:oraloqs,实际输出:q,应该输出r,因为程序中tag改变的条件是:出现的位置在前面且只出现一次,但是这个例子中r在两个o之间,在一次扫描到r的时候,o出现的次数还是1且它比r先出现,所以r不会被记录。将程序改为两次遍历就可以ac。要注意,不能够将字符串排序,排序之后字符出现的先后顺序就无效了。

#include<iostream>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
int main() {
    string str;
    while (getline(cin, str)) {
        map<char, int> ans;
        char tag = '0';
        ans[tag] = 2;
        for (int i = 0; i < str.size(); i++) {
            if (ans.count(str[i]) != -1) ans[str[i]]++;
            else ans[str[i]] = 1;
        }
        for (int i = 0; i < str.size(); i++) {
            if (ans[str[i]] == 1 && ans[tag] > 1) {
                tag = str[i];
            }
        }
        if (ans[tag] > 1) cout << "-1" << endl;
        else cout << tag << endl;
    }
    return 0;
}
5、任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对

收获:1、关于素数的判断还是不够熟悉,需要加强记忆;2、一个偶数由两个素数组成,在找到小于等于num/2的最大的素数max之后还需要判断num-max是否为素数。例如108=53+55,55就不是素数。

#include<iostream>
#include<cmath>
using namespace std;
bool IsPrim(int n){
    if(n==1) return false;
    if(n==2||n==3) return true;
    if(n%6!=5&&n%6!=1) return false;
    int num_sqrt=floor(sqrt(n));
    for(int i=5;i<=num_sqrt;i+=6){
        if(n%i==0||n%(i+2)==0) return false;
    }
    return true;
}
int main(){
    int num;
    while(cin>>num){
        int n=num/2;
        int max;
        for(int i=n;i>=2;i--){
            if(IsPrim(i)==true&&IsPrim(num-i)==true){
                max=i;
                break;
            }
        }
        cout<<max<<endl;
        cout<<(num-max)<<endl;
    }
    return 0;
}
6、识别有效的ip地址和掩码并进行分类统计

请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
A类:1个A类网段:10.0.0.0~10.255.255.255
B类:16个B类网段:172.16.0.0~172.31.255.255
C类:256个C类网段:192.168.0.0~192.168.255.255
子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:

  1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
  2. 私有IP地址和A,B,C,D,E类地址是不冲突的
    收获
补充知识点1:Java和C++的区别
  1. Java是解释型语言,所谓的解释型语言,就是源码会先经过一次编译,成为中间码,中间码再被解释器解释成机器码。对于Java而言,中间码就是字节码(.class),而解释器在JVM中内置了。
  2. C++是编译型语言,所谓编译型语言,就是源码一次编译,直接在编译的过程中链接了,形成了机器码。
  3. C++比Java执行速度快,但是Java可以利用JVM跨平台。
  4. Java是纯面向对象的语言,所有代码(包括函数、变量)都必须在类中定义。而C++中还有面向过程的东西,比如是全局变量和全局函数。
  5. C++中有指针,Java中没有,但是有引用。
  6. C++支持多继承,Java中类都是单继承的。但是继承都有传递性,同时Java中的接口是多继承,类对接口的实现也是多实现。
  7. C++中,开发需要自己去管理内存,但是Java中JVM有自己的GC机制,虽然有自己的GC机制,但是也会出现OOM和内存泄漏的问题。C++中有析构函数,Java中Object的finalize方法。
  8. C++运算符可以重载,但是Java中不可以。同时C++中支持强制自动转型,Java中不行,会出现ClassCastException(类型不匹配)。
补充知识点2:软件测试中开发不承认这个bug应该怎么做?
  1. 首先明确开发说不是bug的理由。
  2. 如果是需求变更, 那就找产品经理确认是否是需求变更。
  3. 如果开发说测试环境问题, 让他说明清楚测试环境问题是什么,按照他说的验证一遍, 如果确实如他所说, 关闭bug,但是不是他说的那样,继续激活bug给开发解决,确保产品质量。
  4. 如果开发说用户不存在这种使用场景, 但是我们不认可他说的,把这个bug 知会到测试经理,让测试经理去判定。
补充知识点3:C++中字符串string和整数int的互相转化方式

一、string转int的方式
1、 采用最原始的string, 然后按照十进制的特点进行算术运算得到int,但是这种方式太麻烦,这里不介绍了。
2、采用标准库中atoi函数。

string s = "12";
int a = atoi(s.c_str());

对于其他类型也都有相应的标准库函数,比如浮点型atof(),long型atol()等等。
3、采用sstream头文件中定义的字符串流对象来实现转换。

istringstream is("12"); //构造输入字符串流,流的内容初始化为“12”的字符串
int i;
is >> i; //从is流中读入一个int整数存入i中

二、int转string的方式
1、采用标准库中的to_string函数。

int i = 12;
cout << std::to_string(i) << endl;

不需要包含任何头文件,应该是在utility中,但无需包含,直接使用,还定义任何其他内置类型转为string的重载函数,很方便。
2、采用sstream中定义的字符串流对象来实现。

ostringstream os; //构造一个输出字符串流,流内容为空
int i = 12;
os << i; //向输出字符串流中输出int整数i的内容
cout << os.str() << endl; //利用字符串流的str函数获取流中的内容

字符串流对象的str函数对于istringstream和ostringstream都适用,都可以获取流中的内容。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值