C++编程题(答案)-c++编程题库及答案_第1页
C++编程题(答案)-c++编程题库及答案_第2页
C++编程题(答案)-c++编程题库及答案_第3页
C++编程题(答案)-c++编程题库及答案_第4页
C++编程题(答案)-c++编程题库及答案_第5页
已阅读5页,还剩41页未读, 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C++编程题(答案)_c++编程题库及答案1.温度转换题目描述:编写程序实现摄氏度(C)与华氏度(F)的双向转换,转换公式为:F=C×9/5+32,C=(F-32)×5/9。程序接收用户输入的温度值与单位标识,标识为'C'或'c'时代表输入为摄氏度,需转换为华氏度输出;标识为'F'或'f'时代表输入为华氏度,需转换为摄氏度输出。输入格式:第一行输入一个浮点数代表温度值,第二行输入一个字符代表温度单位,输入保证单位标识为合法值,无需做异常校验。输出格式:输出转换后的温度值,保留2位小数,末尾标注对应单位,例如输入0、c时,输出为32.00F。参考实现:```cppusingnamespacestd;intmain(){doubletemp;charunit;cin>>temp>>unit;cout<<fixed<<setprecision(2);cout<<fahrenheit<<"F"<<endl;}else{doublecelsius=(temp-32)*5.0/9.0;cout<<celsius<<"C"<<endl;}return0;}```代码说明:计算时使用9.0、5.0等浮点数字面量,是为了避免整数除法导致的精度错误——若写为9/5,C++中两个整数相除会截断小数部分得到1,直接导致转换结果偏差。`fixed`与`setprecision(2)`组合使用可固定输出2位小数,即使小数部分为0也会补全,符合格式要求。cin读取字符时会自动跳过前面的空白符(包括输入温度值后残留的换行符),无需额外清理输入缓冲区。2.回文数判断题目描述:给定一个32位有符号整数x,若x是回文整数则输出true,否则输出false。回文数指正序和倒序读完全一致的整数,注意负数不属于回文数(如-121倒序为121-,与原数不符);末尾为0的正整数不可能是回文数,除0本身。输入格式:输入一个32位有符号整数x,取值范围为[-2^31,2^31-1]。输出格式:输出字符串true或false代表判断结果。参考实现:```cppusingnamespacestd;intmain(){intx;cin>>x;return0;}intreverted_half=0;while(x>reverted_half){reverted_half=reverted_half*10+x%10;x/=10;}return0;}```代码说明:本实现采用反转后半段数字的方案,避免全量反转触发整数溢出问题:若将整个数字反转,当输入为2^31-1(2147483647)时,反转结果为7463847412,超出32位有符号整数上限,会触发未定义行为。反转后半段时,循环终止条件为x<=reverted_half,此时reverted_half仅存储数字后半段的反转值,长度不超过原数字的一半,不会溢出。当数字长度为偶数时,循环结束后x与reverted_half长度相等,直接比较即可;当数字长度为奇数时,reverted_half会多存储中间位数字,除以10剔除中间位后再比较即可。前置判断负数、末尾为0的非零数,可减少不必要的计算。3.9*9乘法口诀表打印题目描述:按照标准对齐格式打印9*9乘法口诀表,要求每个乘法项占固定宽度,排版整齐,行尾无多余空格。输入格式:无输入,程序启动后直接输出。输出格式:共9行,第i行(i从1到9)包含i个乘法表达式,格式为“j*i=乘积”,其中j从1到i,每个表达式占8个字符宽度,左对齐。参考实现:```cppusingnamespacestd;intmain(){cout<<left;for(inti=1;i<=9;++i){for(intj=1;j<=i;++j){stringexpr=to_string(j)+"*"+to_string(i)+"="+to_string(i*j);cout<<setw(8)<<expr;}cout<<endl;}return0;}```代码说明:`setw`流操作符仅对紧随其后的第一个输出项生效,因此需要将每个乘法表达式拼接为单个字符串后再设置宽度,否则setw只会作用于表达式的第一个字符(即乘数j),无法实现整体对齐。左对齐标志`left`一旦设置会持续生效,无需在循环中重复设置。内层循环边界严格控制为j<=i,行尾不会产生多余空格。固定8位宽度可保证一位数乘积、两位数乘积都能对齐,避免排版错乱。4.数组元素循环右移题目描述:给定长度为n的整数数组,将元素循环右移k位,要求采用原地算法,空间复杂度为O(1),不得借助额外数组存储。例如数组[1,2,3,4,5,6,7]右移3位后结果为[5,6,7,1,2,3,4]。输入格式:第一行输入两个正整数n(1<=n<=1000)和k(0<=k<=10^6),分别代表数组长度和右移位数;第二行输入n个整数代表数组元素。输出格式:输出右移后的数组,元素间用单个空格分隔,行尾无多余空格。参考实现:```cppusingnamespacestd;voidreverse(vector<int>&nums,intleft,intright){while(left<right){swap(nums[left],nums[right]);left++;right--;}}intmain(){intn,k;cin>>n>>k;vector<int>nums(n);for(inti=0;i<n;++i){cin>>nums[i];}k=k%n;if(k==0){for(inti=0;i<n;++i){if(i>0)cout<<"";cout<<nums[i];}cout<<endl;return0;}reverse(nums,0,n-1);reverse(nums,0,k-1);reverse(nums,k,n-1);for(inti=0;i<n;++i){if(i>0)cout<<"";cout<<nums[i];}cout<<endl;return0;}```代码说明:循环右移k位的本质是将数组末尾k个元素移动到数组开头,三次反转法的数学原理为:设原数组为AB(A为前n-k个元素,B为后k个元素),目标数组为BA。对整个数组反转得到B^TA^T,反转前k个元素得到BA^T,反转后n-k个元素得到BA,正好匹配目标结果。k对n取模是因为右移n位后数组回到初始状态,当k远大于n时可避免无效操作。该实现仅通过元素交换完成移位,空间复杂度O(1),时间复杂度O(n),每个元素最多被交换2次。输出时通过判断i>0打印元素间空格,保证行尾无多余空格。5.矩形类设计题目描述:设计C++类Rectangle表示矩形,需满足以下要求:私有成员变量包括length(长,double类型)、width(宽,double类型);公有构造函数包括无参构造(长、宽初始化为1)、带参构造(接收两个double参数初始化长和宽,参数<=0时默认初始化为1);公有成员函数包括getPerimeter()(返回周长)、getArea()(返回面积)、setLength()(设置长,参数非法时不修改)、setWidth()(设置宽,参数非法时不修改)、getLength()、getWidth()(返回长和宽的值)。输入格式:输入四个浮点数,分别代表无参构造矩形的新长、新宽,带参构造矩形的初始长、初始宽。输出格式:分别输出两个矩形的长、宽、周长、面积,保留2位小数,每个矩形信息占一行,格式为“长:xx宽:xx周长:xx面积:xx”。参考实现:```cppusingnamespacestd;classRectangle{private:doublelength;doublewidth;public:Rectangle():length(1.0),width(1.0){}Rectangle(doublel,doublew){length=(l>0)?l:1.0;width=(w>0)?w:1.0;}voidsetLength(doublel){if(l>0)length=l;}voidsetWidth(doublew){if(w>0)width=w;}doublegetLength()const{returnlength;}doublegetWidth()const{returnwidth;}doublegetPerimeter()const{return2*(length+width);}doublegetArea()const{returnlength*width;}};intmain(){doublel1,w1,l2,w2;cin>>l1>>w1>>l2>>w2;Rectangler1;r1.setLength(l1);r1.setWidth(w1);Rectangler2(l2,w2);cout<<fixed<<setprecision(2);cout<<"长:"<<r1.getLength()<<"宽:"<<r1.getWidth()<<"周长:"<<r1.getPerimeter()<<"面积:"<<r1.getArea()<<endl;cout<<"长:"<<r2.getLength()<<"宽:"<<r2.getWidth()<<"周长:"<<r2.getPerimeter()<<"面积:"<<r2.getArea()<<endl;return0;}```代码说明:类设计严格遵循封装原则:长、宽成员设为私有,外部必须通过公有的set方法修改,set方法内置合法性校验,保证对象状态始终合法,不会出现长或宽为非正数的无意义情况。所有不修改成员变量的方法都添加const修饰,既可以让编译器做语法检查,也支持const对象调用。无参构造使用初始化列表赋值,相比构造函数体内赋值效率更高。6.学生类继承与多态实现题目描述:设计人员基类Person,包含私有成员name(姓名,string)、age(年龄,int),公有构造函数初始化两个成员,公有成员函数showInfo()输出人员基本信息。从Person公有派生学生类Student,增加私有成员stuId(学号,string)、score(分数,double),公有构造函数初始化所有成员,重写showInfo()输出学生完整信息。要求通过基类指针实现多态调用。输入格式:第一行输入姓名、年龄,代表Person对象信息;第二行输入姓名、年龄、学号、分数,代表Student对象信息。输出格式:分别通过基类指针调用两个对象的showInfo(),Person对象输出格式为“人员信息:姓名:xx年龄:xx”,Student对象输出格式为“学生信息:姓名:xx年龄:xx学号:xx分数:xx”,分数保留1位小数。参考实现:```cppusingnamespacestd;classPerson{protected:stringname;intage;public:Person(stringn,inta):name(move(n)),age(a){}virtualvoidshowInfo()const{cout<<"人员信息:姓名:"<<name<<"年龄:"<<age<<endl;}virtual~Person()=default;};classStudent:publicPerson{private:stringstuId;doublescore;public:Student(stringn,inta,stringid,doubles):Person(move(n),a),stuId(move(id)),score(s){}voidshowInfo()constoverride{cout<<"学生信息:姓名:"<<name<<"年龄:"<<age<<"学号:"<<stuId<<"分数:"<<fixed<<setprecision(1)<<score<<endl;}};intmain(){stringname1,name2,id;intage1,age2;doublescore;cin>>name1>>age1;cin>>name2>>age2>>id>>score;Person*p1=newPerson(name1,age1);Person*p2=newStudent(name2,age2,id,score);p1->showInfo();p2->showInfo();deletep1;deletep2;return0;}```代码说明:多态实现需满足三个核心条件:基类将待重写方法声明为虚函数(virtual)、派生类重写虚函数、通过基类指针/引用指向派生类对象。基类将name、age设为protected成员,允许派生类直接访问,简化代码。派生类使用override关键字标记重写方法,可让编译器检查函数签名是否匹配,避免因参数、const属性不匹配导致重写失败。基类析构函数必须声明为虚函数,否则通过基类指针释放派生类对象时,只会调用基类析构函数,派生类资源无法释放,造成内存泄漏。构造函数中使用move转移string所有权,避免不必要的拷贝,提升效率。7.自定义字符串类MyString题目描述:自主实现字符串类MyString,不直接依赖std::string接口,需包含:私有成员char*str(指向堆上存储的字符串)、intlen(字符串长度,不含末尾'\0');公有接口包括无参构造(初始化为空串)、带参构造(接收C风格字符串初始化)、拷贝构造(实现深拷贝)、拷贝赋值运算符(实现深拷贝、处理自赋值)、析构函数(释放堆内存)、c_str()(返回C风格字符串指针)、size()(返回字符串长度)、重载+运算符(实现两个字符串拼接)、重载==运算符(判断字符串内容是否相等)。输入格式:输入两个不含空格的C风格字符串,分别用于初始化两个MyString对象s1、s2。输出格式:分别输出s1、s2的长度和内容,输出s1+s2的拼接结果和长度,输出s1与s2是否相等的判断结果(相等输出1,不等输出0)。参考实现:```cppusingnamespacestd;classMyString{private:char*str;intlen;public:MyString():len(0){str=newchar[1];str[0]='\0';}MyString(constchar*s){if(s==nullptr){len=0;str=newchar[1];str[0]='\0';}else{len=strlen(s);str=newchar[len+1];strcpy(str,s);}}MyString(constMyString&other){len=other.len;str=newchar[len+1];strcpy(str,other.str);}MyString&operator=(constMyString&other){if(this==&other)return*this;delete[]str;len=other.len;str=newchar[len+1];strcpy(str,other.str);return*this;}~MyString(){delete[]str;}constchar*c_str()const{returnstr;}intsize()const{returnlen;}MyStringoperator+(constMyString&other)const{MyStringres;res.len=len+other.len;delete[]res.str;res.str=newchar[res.len+1];strcpy(res.str,str);strcat(res.str,other.str);returnres;}booloperator==(constMyString&other)const{if(len!=other.len)returnfalse;returnstrcmp(str,other.str)==0;}};intmain(){chars1[1000],s2[1000];cin>>s1>>s2;MyStringa(s1),b(s2);cout<<a.size()<<""<<a.c_str()<<endl;cout<<b.size()<<""<<b.c_str()<<endl;MyStringc=a+b;cout<<c.size()<<""<<c.c_str()<<endl;cout<<(a==b?1:0)<<endl;return0;}```代码说明:类的核心是实现深拷贝逻辑:默认生成的拷贝构造、拷贝赋值仅会拷贝指针的地址值(浅拷贝),导致两个对象的str指向同一块堆内存,析构时会出现重复释放崩溃。深拷贝需要为新对象申请独立的堆内存,拷贝原对象的字符串内容,保证对象间内存互不干扰。拷贝赋值运算符必须做自赋值检查,若传入对象为自身,直接返回即可,否则先释放自身内存再拷贝会访问野指针。+运算符重载必须返回值类型,不能返回引用,因为拼接结果是临时对象,函数结束后临时对象销毁会导致引用无效。带参构造需要处理空指针输入,避免strlen访问空指针崩溃。8.学生成绩排序题目描述:有n名学生的成绩信息,包含学号、姓名、语文、数学、英语三科成绩,计算每个学生的总分,按规则排序:总分从高到低,总分相同则数学成绩从高到低,数学成绩也相同则学号从小到大。输入格式:第一行输入正整数n(1<=n<=1000)代表学生人数;接下来n行,每行输入学号(10位字符串)、姓名(不超过10位字符串)、语文、数学、英语成绩(均为0-100的整数)。输出格式:输出排序后的学生信息,每行包含学号、姓名、三科成绩、总分,字段间用单个空格分隔。参考实现:```cppusingnamespacestd;structStudent{stringid;stringname;intchinese;intmath;intenglish;inttotal;};intmain(){intn;cin>>n;vector<Student>stus(n);for(inti=0;i<n;++i){cin>>stus[i].id>>stus[i].name>>stus[i].chinese>>stus[i].math>>stus[i].english;stus[i].total=stus[i].chinese+stus[i].math+stus[i].english;}sort(stus.begin(),stus.end(),[](constStudent&a,constStudent&b){if(a.total!=b.total)returna.total>b.total;if(a.math!=b.math)returna.math>b.math;returna.id<b.id;});for(constauto&s:stus){cout<<s.id<<""<<<<""<<s.chinese<<""<<s.math<<""<<s.english<<""<<s.total<<endl;}return0;}```代码说明:使用vector存储学生信息,相比原生数组更灵活,内存管理更安全。sort是STL的内省排序实现,时间复杂度O(nlogn),支持自定义比较规则。这里使用C++11lambda表达式作为比较函数,代码更紧凑。比较函数规则为:当a应该排在b前面时返回true,因此总分、数学成绩高的比较时返回大于号结果,学号小的返回小于号结果(string默认<运算符实现字典序升序比较)。输入时提前计算总分,避免排序比较时重复计算,提升效率。9.括号匹配校验题目描述:给定仅包含'('、')'、'['、']'、'{'、'}'的字符串,判断括号是否有效:左括号必须用相同类型的右括号闭合,左括号必须按正确顺序闭合,空字符串为有效。输入格式:输入一行字符串,长度不超过10000,仅包含上述6种字符。输出格式:有效输出true,否则输出false。参考实现:```cppusingnamespacestd;intmain(){strings;cin>>s;stack<char>st;for(charc:s){if(c=='(')st.push(')');elseif(c=='[')st.push(']');elseif(c=='{')st.push('}');else{return0;}st.pop();}}cout<<(st.empty()?"true":"false")<<endl;return0;}```代码说明:栈的后进先出特性完美匹配括号匹配逻辑:最后出现的左括号需要最先闭合。实现时采用优化技巧:遇到左括号时压入对应的右括号,遇到右括号时直接对比栈顶即可,无需额外判断括号对应关系。算法覆盖三种错误场景:遇到右括号时栈为空(右括号无匹配左括号)、栈顶与当前右括号不匹配(括号类型错误)、遍历结束后栈非空(左括号无匹配右括号)。时间复杂度O(n),每个字符入栈出栈各一次,空间复杂度最坏O(n)(全为左括号的场景)。10.单词频率统计题目描述:给定一段英文文本,统计每个单词出现的频率,按规则输出:频率从高到低,频率相同则按单词字典序从小到大。单词定义为连续的英文字母组成的序列,不区分大小写,数字、标点、空格均为单词分隔符。输入格式:输入一行文本,长度不超过100000,包含可打印ASCII字符。输出格式:每行输出一个单词和对应次数,单词全小写,单词与次数间用单个空格分隔。参考实现:```cppusingnamespacestd;intmain(){strings;getline(cin,s);unordered_map<string,int>freq;stringword;for(charc:s){if(isalpha(c)){word+=tolower(c);}else{if(!word.empty()){freq[word]++;word.clear();}}}if(!word.empty())freq[word]++;vector<pair<string,int>>vec(freq.begin(),freq.end());sort(vec.begin(),vec.end(),[](constpair<string,int>&a,constpair<string,int>&b){if(a.second!=b.second)returna.second>b.second;returna.first<b.first;});for(constauto&p:vec){cout<<p.first<<""<<p.second<<endl;}return0;}```代码说明:因为输入包含空格,所以用getline读取整行输入。单词分割逻辑为遍历每个字符,字母转小写后追加到临时单词,非字母则视为单词边界,临时单词非空时计入频率统计。遍历结束后需要处理最后一个单词(文本末尾为字母时,循环内不会触发计入逻辑)。频率统计使用unordered_map,底层为哈希表,插入查找平均O(1),比红黑树实现的map效率更高。由于unordered_map无序且无法按值排序,因此将键值对拷贝到vector后自定义排序。isalpha、tolower函数来自cctype头文件,兼容性好,不受区域设置影响。11.0-1背包问题题目描述:有一个容量为W的背包,n件物品的重量为w[i]、价值为v[i],每件物品只能选或不选(不可分割),求背包能装下的最大总价值。输入格式:第一行输入n(1<=n<=100)和W(1<=W<=1000),分别代表物品数和背包容量;第二行输入n个正整数代表各物品重量;第三行输入n个正整数代表各物品价值。输出格式:输出一个整数代表最大总价值。参考实现:```cppusingnamespacestd;intmain(){intn,W;cin>>n>>W;vector<int>w(n),v(n);for(inti=0;i<n;++i)cin>>w[i];for(inti=0;i<n;++i)cin>>v[i];vector<int>dp(W+1,0);for(inti=0;i<n;++i){for(intj=W;j>=w[i];--j){dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}}cout<<dp[W]<<endl;return0;}```代码说明:本实现采用一维滚动数组优化空间复杂度,dp[j]表示容量为j的背包能装的最大价值,初始状态全为0(无物品时价值为0)。状态转移逻辑为:对每个物品,有选和不选两种选择,不选则dp[j]保持原值,选则预留w[i]容量,加上当前物品价值,取两者最大值。必须倒序遍历容量的原因是保证每个物品只被选一次:倒序时dp[j-w[i]]存储的是上一轮(未选当前物品)的结果,正序遍历会导致dp[j-w[i]]在本轮被提前更新,相当于同一物品被多次选择,退化为完全背包问题。该实现时间复杂度O(nW),空间复杂度O(W),相比二维数组方案空间效率大幅提升。12.二叉树层序遍历题目描述:给定一棵二叉树,按层序遍历方式返回节点值,即逐层从左到右访问所有节点。二叉树节点结构为:structTreeNode{intval;TreeNode*left;TreeNode*right;TreeNode(intx):val(x),left(nullptr),right(nullptr){}};输入格式:输入为层序序列化的二叉树字符串,节点值用逗号分隔,空节点用"null"表示,例如"1,2,3,null,null,4,5"代表根节点为1,左孩子2、右孩子3,2的左右孩子为空,3的左孩子4、右孩子5。输出格式:按层输出,每层节点值用空格分隔,层与层之间换行。参考实现:```cppusingnamespacestd;structTreeNode{intval;TreeNode*left;TreeNode*right;TreeNode(intx):val(x),left(nullptr),right(nullptr){}};vector<string>split(conststring&s,chardelim){vector<string>tokens;stringtoken;istringstreamtokenStream(s);while(getline(tokenStream,token,delim)){tokens.push_back(token);}returntokens;}intmain(){

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论