文章目录

  • 1.删除字符串中的指定字符
    • 1.1 问题描述
    • 1.2 问题求解
  • 2.成绩排名
    • 2.1 问题描述
    • 2.2 问题求解
  • 3.字符串变换最小费用
    • 3.1 问题描述
    • 3.2 递归法求解
    • 3.2 动态规划法求解
  • 参考文献

1.删除字符串中的指定字符

1.1 问题描述

输入两个字符串M和N,从字符串M中删除字符串N中所有的字符。例如,输入”abcda”和”ac”,则删除之后的第一个字符串变成”bd”。

1.2 问题求解

这个比较简单,给出如下参考代码:

#include <string>
using namespace std;void deleteCharacter(string& str0,string& str1){for(int i=0;i<str0.length();){if(str1.find(str0[i])!=string::npos){str0.erase(i,1);continue;}++i;}
}

2.成绩排名

2.1 问题描述

题目总共包含如下两种格式的字符串命令:
LOD GRADE命令,其格式:
LOD GRADE:NAME=XiaoMing,MATH=80,LANG=90;
(1) 此命令用于导入学生成绩
(2) NAME字段表示学生姓名
(3) MATH字段表示学生数学成绩
(4) LANG字段表示语文成绩
(5) MATH字段和LANG字段顺序不一定MATH在前,LANG在后
(6) 相同的分数,名次相同,后面的名次空缺;例如100,99,99,99,98,98,名次:1,2,2,2,5,5
(7) 此命令会连续执行,直到遇到第一个LST GRADE

LST GRADE命令,其格式:
LST GRADE:NAME=XiaoMing;
(1) 此命令用于查询学生成绩
(2) NAME字段表示学生姓名
(3) 查询结果格式:姓名 数学 语文 总分 数学排名 语文排名 总排名
(4) 每组用例,此命令仅执行一次

输入: 连续多组LOD GRADE后跟一个LST GRADE查询命令
输出: 输出查询格式为:
姓名 数学 语文 总分 数学排名 语文排名 总排名
样例输入: LOD GRADE:NAME=XiaoMing,MATH=80,LANG=90;
LOD GRADE:NAME=XiaoHong,LANG=60,MATH=100;
LOD GRADE:NAME=XiaoMei,MATH=70,LANG=90;
LST GRADE:NAME=XiaoHong;
样例输出: XiaoHong 100 60 160 1 3 2

2.2 问题求解

此问题也不难,没有涉及到复杂的算法,就是比较繁琐,主要考察数据的表示,字符串的提取与排序,下面给出参考代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;struct Student {string name;int math;int lang;Student(){this->name="";this->math=0;this->lang=0;}Student(string name,int math,int lang){this->name=name;this->math=math;this->lang=lang;}bool operator==(const Student& ele){return this->name==ele.name;}
};//自定义比较函数,数学排名
bool compareMath(const Student& left,const Student& right){return left.math>right.math; //降序排列
}//自定义比较函数,语文排名
bool compareLang(const Student& left,const Student& right){return left.lang>right.lang; //降序排列
}//自定义比较函数,总分排名
bool compareTotal(const Student& left,const Student& right){return left.math+left.lang>right.math+right.lang; //降序排列
}int main(){vector<Student> studentVec;string input;Student student;vector<string> splitedRes;while(getline(cin,input)){int s=input.find("NAME=");int e=input.find(',',s);if(input.find("LOD GRADE")!=string::npos){  //输入成绩student.name=input.substr(s+5,e-s-5);s=input.find("MATH=");e=input.find(',',s);if(e==string::npos) e=input.length()-1;student.math=stoi(input.substr(s+5,e-s-5));s=input.find("LANG=");e=input.find(',',s);if(e==string::npos) e=input.length()-1;student.lang=stoi(input.substr(s+5,e-s-5));studentVec.push_back(student);}else {                                     //查询成绩e=input.length()-1;string name=input.substr(s+5,e-s-5);Student student;//数学排名std::sort(studentVec.begin(),studentVec.end(),compareMath);vector<Student>::iterator it=find(studentVec.begin(),studentVec.end(),Student(name,0,0));student=*it;while(it!=studentVec.begin()&&(it-1)->math==it->math) --it;int mathRank=it-studentVec.begin()+1;//语文排名std::sort(studentVec.begin(),studentVec.end(),compareLang);it=find(studentVec.begin(),studentVec.end(),Student(name,0,0));while(it!=studentVec.begin()&&(it-1)->lang==it->lang) --it;int langRank=it-studentVec.begin()+1;//总分排名std::sort(studentVec.begin(),studentVec.end(),compareTotal);it=find(studentVec.begin(),studentVec.end(),Student(name,0,0));while(it!=studentVec.begin()&&(it-1)->math+(it-1)->lang==it->math+it->lang) --it;int totalRank=it-studentVec.begin()+1;cout<<student.name<<" "<<student.math<<" "<<student.lang<<" "<<student.math+student.lang<<" "<<mathRank<<" "<<langRank<<" "<<totalRank<<endl;studentVec.clear();}}getchar();
}

3.字符串变换最小费用

3.1 问题描述

给出两个字串A,B。将A字串转化为B字串,转化一共有两种方式:删除连续的n个字符,一次操作费用为2。增加连续的n个字符(增加的字符是什么由你决定),一次操作费用为n+2。求把A变为B最小费用。

输入:
第一行输入一个正整数T(1 <= T <= 10),表示有T组测试数据。
对于每组测试数据,有两行字符串A, B(字符串长度不超过2000,字符仅包含小写字母)。

输出:
对于每组测试数据,输出一行一个整数,表示最小费用。

样例输入:

2
dsafsadfadf
fdfd
aaaaaaaa
bbbbbbbb

样例输出:

7
12

答案提示:
“dsafsadfadf” 变成 “fdfd” 最少的代价的一种方法是:
(1)“dsafsadfadf” -> “f” 删除连续的10个,代价2 ;
(2)“f” -> “fdfd” 增加连续的3个(”dfd”),代价为3 + 2 = 5
总共的最小代价为2 + 5 = 7,其他方法的代价都不小于7 。
“aaaaaaaa” 变成 “bbbbbbbb” 最小代价的一种方法是:
(1)“aaaaaaaa” 全部删除,代价2;
(2)增加8个连续的’b’,代价10 。
总共的最小代价为2 + 10 = 12 。
注意,有些最优的方案可能要做多次的删除和增加操作,不限于两次。

3.2 递归法求解

问题分析:
从给定的问题描述,我们可以得到如下几条信息:
(1)A串变为B串,只有两种变换的方式,一是删除,二是增加。增加和删除的位置可以在A串中的任意位置;
(2)每一次删除和增加都需要额外的代价,因此,对同一段字符,应该使用贪心思想,尽可能的连续删除和连续增加;
(3)A串和B串的相同的首尾子串是不需要考虑的。

除去相同的首尾子串,得到的子串A’和B’,将A’变为B’时,因为此时的A’的首尾字符与B’的首尾字符是不相同的,所以,对A’此时的操作有两种:
(1)对A’从左起和右起使用贪心的思想删除连续的字符;
(2)对A’从左起和右起用贪心的思想分别增加B’的左起连续的字符和B’的右起连续的字符。
这里为什么不考虑从A的中间部分开始插入和删除,是因为这样做的话,A’的首尾位字符与B’的首尾字符还是不相同,还是需要进行删除或者增加的操作,很明显这样不是最优的,所以抛弃这种做法。

具体实现请,参考如下代码:

/*******************************************
*@brief:将字符串a变为字符串b的最小费用
*@param:a:字符串a;b:字符串b;i:a的起始下标;ir:a的结束下标;j:b的起始下标;jr:b的结束下标
*******************************************/
int func1 (const char a[] ,const char b[] ,int i ,int ir ,int j ,int jr) {//ab有相同前缀,则去除掉也不影响while (i <= ir && j <= jr && a[i] == b[j]) {i++ ;j++ ;}// ab有相同后缀,则去除掉也不影响while (i <= ir && j <= jr && a[ir] == b[jr]) {ir-- ;jr-- ;}if (i > ir) {//如果a是空串,则只需增加操作,代价是b的长度+2return (jr + 1 - j) + 2 ;} else if (j > jr) {//如果b是空串,则只需删除操作,代价是2return 2 ;}//如果ab无公共前后缀,则代价是求a的所有前后子串转为b的最小值//最坏的情况是将a全部删除再增加到bint tmp = 2 + (jr + 1 - j) + 2 ;//a的非空后子串for (int k = i + 1 ; k <= ir ; k++)tmp = min (tmp ,2 + func1 (a ,b ,k ,ir ,j ,jr)) ;//a的非空前子串for (int k = ir - 1 ; k >= i ; k--)tmp = min (tmp ,2 + func1 (a ,b ,i ,k ,j ,jr)) ;//在a的左边增加连续的b的非空前子串for (int k = j + 1 ; k <= jr ; k++)tmp = min (tmp ,(k - j) + 2 + func1 (a ,b ,i ,ir ,k ,jr)) ;//在a的右边增加连续的b的非空后子串for (int k = jr - 1 ; k >= j ; k--)tmp = min (tmp ,(jr - k) + 2 + func1 (a ,b ,i ,ir ,j ,k)) ;return tmp ;
}

运行结果:

cout<<func1("1aaa1","aaa",0,4,0,2)<<endl;  //输出4
cout<<func1("aaa","1aaa1",0,2,0,4)<<endl;  //输出6

3.2 动态规划法求解

递归法易于理解,但是存在对子问题的重复计算,时间效率低下,可以将子问题的结果存储起来,把递归实现,转换为迭代实现,这样就变成了动态规划。

递归法是自顶向下,而动态规划是自底向上递归法是需要某个结果时就调用自己来计算,动态规划把每次递推的结果保存在数组中。因为这里有i,ir,j,jr一个4个变量,所以其实需要一个4维数组,这里用了一个宏代替,将4维数组通过下标转变变为一维数组。

具体实现参考如下代码:

int func2 (const string &a, const string &b)  {const int la = (int) a.length () ;const int lb = (int) b.length () ;vector<int> ret (la * la * lb * lb) ;#define VRET(a ,b ,c ,d) (ret[(a) * la * lb * lb + (b) * lb * lb + (c) * lb + (d)])for (int ix = la - 1 ; ix >= 0 ; ix--)for (int irx =ix ; irx < la ; irx++)for (int jx = lb - 1 ; jx >= 0 ; jx--)for (int jrx =jx ; jrx < lb ; jrx++) {int i = ix ;int ir = irx ;int j = jx ;int jr = jrx ;while (i <= ir && j <= jr && a[i] == b[j]) {i++ ;j++ ;}while (i <= ir && j <= jr && a[ir] == b[jr]) {ir-- ;jr-- ;}if (i > ir) {         //A为空串VRET (ix ,irx ,jx ,jrx) = (jr + 1 - j) + 2 ;continue ;} else if (j > jr) {    //B为空串VRET (ix ,irx ,jx ,jrx) = 2 ;continue ;}int tmp = 2 + (jr + 1 - j) + 2 ;   //最坏情况,将A全部删除再增加到Bfor (int k = i + 1 ; k <= ir ; k++) tmp = min (tmp ,2 + VRET (k ,ir ,j ,jr)) ;for (int k = ir - 1 ; k >= i ; k--)tmp = min (tmp ,2 + VRET (i ,k ,j ,jr)) ;for (int k = j + 1 ; k <= jr ; k++)tmp = min (tmp ,(k - j) + 2 + VRET (i ,ir ,k ,jr));for (int k = jr - 1 ; k >= j ; k--)tmp = min (tmp ,(jr-k) + 2 + VRET (i ,ir ,j ,k));VRET (ix ,irx ,jx ,jrx) = tmp ;continue ;}return VRET (0 ,la - 1 ,0 ,lb - 1) ;#undef VRET
}

运行结果:

cout<<func2("dsafsadfadf","fdfd")<<endl;   //7
cout<<func2("aaaaaaaa","bbbbbbbb")<<endl;  //12

参考文献

CSDN论坛

华为 2017 秋季校招笔试题(C++ 后台)相关推荐

  1. CVTE 2017 秋季校招笔试题回忆(C++后台)

    1.概述 2016.09.06 晚参加了 CVTE C++ 岗的在线笔试.笔试题型分为不定向选择题和编程题,总共 27 题.其中不定项选择题为 25 道,编程题 2 道.其特点是不定项选择题不告诉你是 ...

  2. CVTE 2017 秋季校招一面(C++ 后台)

    文章目录 0.前言 1.找出数组中第 k 大的数(手写代码) 2.从n个数中找出最小的k个数(n>>k),最优平均时间复杂度是多少 4.C 如何模拟实现 C++ 的类? 5.TCP 与 U ...

  3. 华为 2017 实习生招聘笔试题

    最近几年HUAWEI的利润日胜一日,所以雇员价格也是水涨船高.本次网上编程时间是2017年3月17日晚上7点,共3个小编程题 题目一太简单了~~,就是把控制台输入的字符串小写转大写,忽略非字母字符. ...

  4. 2017京东校招笔试题

    题目内容来自牛客网https://www.nowcoder.com/ta/2017test 1.进制均值 题目描述 尽管是一个CS专业的学生,小B的数学基础很好并对数值计算有着特别的兴趣,喜欢用计算机 ...

  5. 暴风影音2017年校招笔试题-选择题

    1.静态变量通常存储在进程的哪个区?() A.栈区. B.全局区 C.堆区 D.代码区 2.已知一棵二叉树,如果中序遍历的节点顺序是3415726,后序遍历是3147625,则先序遍历结果是:() A ...

  6. 02 2018美团机器学习职位秋季校招笔试题及解答

    目录 一.逻辑题 01. 第一题 02. 第二题 03. 第三题 04. 第四题 05. 第五题 06. 第六题 07. 第七题 08. 第八题 09. 第九题 10. 第十题 11. 第十一题 12 ...

  7. 凑硬币(58同城2017校招笔试题)

    凑硬币(58同城2017校招笔试题) 暴力破解,循环递归实现,代码如下: /** * 暴力破解,循环递归,找出了所有可能的组合并进行了存储,* 在循环递归的时候,因为选取的分类相互是有重叠的,生成的递 ...

  8. 九月十月 阿里 百度 华为 校招笔试题

    九月迅雷,华为,阿里巴巴,最新笔试面试十题 8月15日,百度2道面试题: 1.来自<编程之美>的概率题:一个桶里面有白球.黑球各100个,现在按下述规则取球:的     i .每次从通里面 ...

  9. 关于python类的继承正确的说法是_2017美团点评的运维岗校招笔试题,测测你会几题?...

    原标题:2017美团点评的运维岗校招笔试题,测测你会几题? 1.数据库:以下哪项不是HASH索引的特征? A MySQL不能确定在两个值之间大约有多少行 B 不能使用hash索引来加速ORDER BY ...

最新文章

  1. cisco路由器与QOS技术
  2. goldengate Linux平台Oracle RAC-Oracle
  3. 腾讯开源视频动作检测算法DBG,打破两项世界纪录!
  4. c4d阿诺德渲染器支持a卡吗_C4D常用的4大主流渲染器如何选择与比较 (OC/RS/VR/阿诺德)?...
  5. 基于C#语言Windows窗体应用(.Net Framework)的教室点名系统V1.0
  6. 7种常见的音频格式简析 MP3,WMA,WAV,APE,FLAC,OGG,AAC
  7. 差异表达基因变化倍数_差异表达基因
  8. JUNIPER防火墙网页无法登陆时后台配置
  9. mocha java mv_代码覆盖Mocha
  10. OJ刷题 |超大目标值(1亿)求质数个数问题
  11. 五花八门的\异地恋\大结局
  12. Linux——基于GPU的超低延迟远程桌面Parsec
  13. ipad一直卡在白苹果_iPad 为什么至今都没有天气和计算器应用?苹果回答来了
  14. win10系统还原被组策略关闭怎么解决
  15. 2021年最热门的7种编程语言,我选python,你选什么?
  16. Artix-7 and Spartan-7 FPGAs DDR2/DDR3 PCB设计指导
  17. 关于Unity中粒子效果的使用
  18. C/C++教程 第二十七章 —— 脚本开发
  19. C++题解:[NOIP2008pj]立体图
  20. 说说Cisco Packet Tracer的各种汉化中文语言包

热门文章

  1. 卡巴斯基称新型黑客雇佣组织正在攻击欧洲律所
  2. 由35国42家电力输送系统运营商组成的欧洲电力协会网络遭攻击
  3. 分享Java 中如何运行字符串表达式?
  4. 英国脱欧:3/4的技术初创公司将面临严峻时期
  5. Thinkphp 实现上一篇与下一篇的方法
  6. Docker到底是什么?为什么它这么火!
  7. Session重点整理
  8. ORACLE SQL - UPDATE、DELETE、INSERT优化和使用技巧
  9. Delphi 的消息机制浅探二
  10. hp eva 4400存储配置手记