C++基础语法练习题
编程语言的练习最终还是需要通过编程实践才能更好地理解其中的奥秘。纯看黑马视频学了一段时间的C++,回过头来感觉还是很空泛,很多东西都忘记了,导致在笔试中遇见代码题感觉非常陌生。
虽然视频讲解很清楚,但是自身并没有很深刻的认知。因此决定记录下自己在学习基础语法时候用来练习的实践代码。这里仅保存了出错的题目,就当做是一个错题本吧。
PS: 题目是跟着牛客上的编程专项训练完成的,专门用于巩固基础语法知识,难度不大。
变量基本定义
1.实现四舍五入
描述
将浮点数转换为整数类型,要求四舍五入。
输入描述:
随机输入的浮点数
输出描述:
四舍五入之后的整数
举例:输入 14.99 输出 15
实现demo:
#include <iostream>
using namespace std;
//我的方法,经过报错提示才解决了
int main() {
double a;
int b;
cin>>a;
if(abs(a-int(a))>=0.5)
{
if(a>0)
{cout<<int(a)+1<<endl;}
else
{cout<<int(a)-1<<endl;}
}
else
{
cout<<int(a)<<endl;
}
}
// 64 位输出请用 printf("%lld")
//简单直接的方法
#include <iostream>
using namespace std;
int main() {
double d;
cin >> d;
// write your code here......
if(d > 0)
cout<<(int)(d+0.5);
else cout<<(int)(d-0.5);
return 0;
}//这是游戏编程中的常用方法
2.取两个数中较大的数
使用现成的max函数,一行代码解决问题。然而也有网友表示,可以使用逻辑判断语言实现:(a>b?a:b)。
个人认为这种思想有助于在笔试中不允许使用库函数的情况下解决问题。
3.三元素求最大值
max(c,max(a,b)); //使用函数嵌套,可以使代码更简洁,但是不一定更节省存储空间
4.输出水仙花数
描述
水仙花数是指一个三位数,其各位数字的立方和等于该数本身
请输出所有的水仙花数,一行一个
#include <iostream>
using namespace std;
void shuixian(int num)
{
int sum=0;
int value=num;
while(num)
{
sum+=(num%10)*(num%10)*(num%10);
num=num/10;
}
if(sum==value)
cout<<sum<<endl;
}
int main() {
// write your code here......
int a;
int sum=0;
for(a=100;a<1000;a++)
{
shuixian(a);
}
return 0;
}
5.打印乘法表
#include <iostream>
using namespace std;
void cfb(int num)
{
int i,j;
for(j=1;j<=num;j++)
{
for(i=1;i<=j;i++)
cout<<i<<" * "<<j<<" = "<<i*j<<" ";
cout<<endl;
}
}
int main() {
int n;
cin >> n;
// write your code here......
cfb(n);
return 0;
}
6.规律数列求和
描述
有数列为:9,99,999,…,9999999999(10个9)。要求使用循环结构编写程序计算此数列的和,并在控制台输出结果。
#include <iostream>
using namespace std;
int main() {
long long num=0;
long long sum=0;
// write your code here......
for(int i=1;i<=10;i++)
{
num=num*10+9;
sum+=num;
// cout<<sum<<endl;
}
cout<<sum<<endl;
return 0;
}
//之前这个代码一直报错,是因为取值范围出现了问题。
//牛客中提供的应该是C++11的语言规则,所以定义变量为int
//对于这道题来说取值范围的设定时不够的,需要使用长整型变量,即long long型数据。
7.计算小球走过的路程和反弹高度
描述:
一球从 h 米高度自由落下,每次落地后反跳回原高度的一半再落下,求它在第 n 次落地时共经过了多少米?第 n 次返弹多高?
输入描述:
输入小球下落的高度和落地的次数(先输入小球初始高度再输入反弹次数)
输出描述:
输出小球第 n 次 落地时经过的距离和第 n 次反弹的高度(保留小数点后1位)
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
// 下落的高度和落地的次数
double h;
int n;
cin >> h;
cin >> n;
double distance=h;
// write your code here......
for(int i=1;i<n;i++)
{
h=h/2;
distance+=2*h;
}
h=h/2;//补充这一句代码,因为第n次反弹的高度在第n次落地之后第(n+1)次落地之前
cout<<fixed<<setprecision(1)<<distance<<" "<<setprecision(1)<<h<<endl;
//C++中设置保留固定的小数点后位数的表达方式 fixed<<setprecision(d),d=需要保留的位数
return 0;
}
8.判断一个数是不是质数
技巧
如果一个数除了被1和它本身整除,不能被其它任何数整除,则这个数是质数。所以只需要验证输入的数字n能否被2到n-1之间的任何数整除。
再进一步思考,如果n能被一个大于sqrt(n)的数整除,我们不妨设这个大于
sqrt(n)的数为t,则n也一定能被n/t整除,而n/t是小于
sqrt(n)的,所以只需验证输入的数字n能否被2到sqrt(n)之间的任何数整除。
方法一:
#include <cmath>
#include <iostream>
using namespace std;
int main() {
// write your code here......
int val;
int i;
int flag=0;
cin>>val;
for(i=2;i<=val;i++)
{
if(val%i==0)
flag++;
}
if(flag==1)
cout<<"是质数"<<endl;
else
cout<<"不是质数"<<endl;
return 0;
}
方法二:
#include <iostream>
using namespace std;
//判断是否是质数
bool isPrime(int x){
for(int i=2;i*i<=x;i++){
//如果一个数能被2到根号x之间的任意一个数整除,则不是质数
if(x%i==0){
return false;
}
}
return true;
}
int main() {
int num;
cin>>num;
if(isPrime(num)){
cout<<"是质数"<<endl;
}
else{
cout<<"不是质数"<<endl;
}
return 0;
}
9.判断一个数是不是质数
描述
键盘随机输入 6 个整数,将这些数据保存到数组中,先将数组中元素按照格式输出,然后再将数组元素反转,最后按照格式再次输出数组元素。
输入描述:
键盘随机输入 6 个整数
输出描述:
第一次按照格式输出数组中元素,每个元素中间使用逗号和空格隔开,整体使用中括号括起来。
例如:[5, 12, 80, 7, 15, 60]
第二次按照格式输出反转后数组中元素,每个元素中间使用逗号和空格隔开,整体使用中括号括起来。
例如:[60, 15, 7, 80, 12, 5]
#include <iostream>
using namespace std;
int main() {
int arr[6] = { 0 };
int len = sizeof(arr) / sizeof(int);
for (int i = 0; i < len; i++) {
cin >> arr[i];
}
cout << "[";
for (int i = 0; i < len; i++) {
if (i == len - 1) {
cout << arr[i] << "]" << endl;
break;
}
cout << arr[i] << ", ";
}
// write your code here......
cout << "[";
for (int i = len-1; i >=0; i--) {
if (i == 0) {
cout << arr[i] << "]" << endl;
break;
}
cout << arr[i] << ", ";//确保符合格式要求的好方法
}
return 0;
}
10.C++冒泡排序
冒泡排序法的基本原理就是比较相邻元素,不断将较大的元素交换到右边。冒泡排序对于两个值相同的元素,不会在排序后改变其相对位置,因此是一种稳定算法。
具体的解释可参照:https://blog.csdn.net/m0_73125687/article/details/127338026
#include <iostream>
using namespace std;
int main() {
int arr[6] = { 0 };
int len = sizeof(arr) / sizeof(int);
int temp;
for (int i = 0; i < len; i++) {
cin >> arr[i];
}
// write your code here......
for(int i=0;i<len-1;i++)
{
for(int j=i+1;j<len;j++)
{
if(arr[j]<arr[i])
{
temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
for(int i=0;i<len-1;i++)
cout<<arr[i]<<" ";
cout<<arr[len-1]<<endl;
return 0;
}
C++有自带的swap函数,可改写为
#include <iostream>
using namespace std;
int main() {
int arr[6] = { 0 };
int len = sizeof(arr) / sizeof(int);
for (int i = 0; i < len; i++) {
cin >> arr[i];
}
for(int i = 0; i < len - 1; i++){
//第i趟比较
for(int j = 0; j < len - i - 1; j++){
//开始进行比较,如果arr[j]比arr[j+1]的值大,那就交换位置
if(arr[j] > arr[j + 1]){
swap(arr[j], arr[j + 1]);
}
}
}
for(int i = 0; i < len; i++) //输出
cout << arr[i] << " ";
return 0;
}
11.C++选择排序
对于一个数组arr[len],循环遍历数组,每一次循环从第arr[i]开始,直到arr[len]结束,找到最小的值与arr[i]位置上的值互换。
#include <iostream>
using namespace std;
int main() {
int arr[6] = { 0 };
int len = sizeof(arr) / sizeof(int);
for (int i = 0; i < len; i++) {
cin >> arr[i];
}
int temp;
// write your code here......
for(int i=0;i<len-1;i++)
{
temp=arr[i];
for(int j=i+1;j<len;j++)
{
if(arr[j]<temp)
{
temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
for (int i = 0; i < len; i++)
cout << arr[i] << " ";
cout << endl;
return 0;
}
12.字符串拼接
描述
键盘输入两个字符串,将这两个字符串进行拼接后输出。
输入描述:
键盘输入两个字符串
输出描述:
输出两个字符串拼接后的结果
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1, s2;
getline(cin, s1);//getline获取字符串的函数,需要熟练掌握
getline(cin, s2);
// write your code here......
// string s3;
s1=s1+s2;//避免新增定义s3可以节省空间,但是运行速度会慢几十秒
//对于较复杂的编程题,为了满足空间和时间复杂度限制,就看你怎么选了
cout<<s1<<endl;
return 0;
}
13.结构体的简单使用
定义一个学生结构体,输入内容再按照要求的格式输出
#include <iostream>
#include <string>
using namespace std;
struct student {
// write your code here......
string name;
int age;
double height;
};
int main() {
// write your code here......
student a;
cin>>a.name>>a.age>>a.height;
cout<<a.name<<" "<<a.age<<" "<<a.height;
return 0;
}
14.指针遍历数组
随机输入一组数,按照要求的格式输出。其中,要求以指针的形式遍历数组空间。
#include <iostream>
using namespace std;
int main() {
int arr[6] = { 0 };
int* ptr = arr;
int len = sizeof(arr) / sizeof(int);
for (int i = 0; i < len; i++) {
cin >> arr[i];
}
// write your code here......
for(int i=0;i<len;i++)
{
cout<<*ptr<<" ";
ptr++;
}
return 0;
}
15.指针遍历数组
随机输入一组数,按照要求的格式输出。其中,要求以指针的形式遍历数组空间。
#include <iostream>
using namespace std;
int main() {
int arr[6] = { 0 };
int* ptr = arr;
int len = sizeof(arr) / sizeof(int);
for (int i = 0; i < len; i++) {
cin >> arr[i];
}
// write your code here......
for(int i=0;i<len;i++)
{
cout<<*ptr<<" ";
ptr++;
}
return 0;
}
16. 获取字符串长度
描述
键盘输入一个字符串,编写代码获取字符串的长度并输出,要求使用字符指针实现。
输入描述:
键盘输入一个字符串
输出描述:
输出字符串的长度
字符串函数使用小知识:
cin.getline() // 接受一个字符串,可以接收空格并输出
getline() // 接受一个字符串,可以接收空格并输出,需有“#include”
cin<<的结束符有enter space tab
cin.get()的结束符只有enter,但会把enter放入队列等待
cin.getline()的结束符也只有enter,但不会把enter放入队列
输入的字符串是一个字符数组,采用getline函数输入,这样会在输入的末尾增加一个’\0’表示字符串的结束
#include <iostream>
using namespace std;
int main() {
char str[100] = { 0 };
cin.getline(str, sizeof(str));
int len=0;//初始化没赋值,最后编译会出错
char *p=str;
// write your code here......
while(*p!='\0')
{
len++;
//str++;//如果不定义p指针,为什么只用str会报错呢?
p++;
}
cout<<len<<endl;
return 0;
}
17. 复制一部分字符串
描述
键盘输入一个长度为len(1 <= len < 30)的字符串,再输入一个正整数 m(1 <= m <= len),将此字符串中从第 m 个字符开始的剩余全部字符复制成为另一个字符串,并将这个新字符串输出。要求用指针处理字符串。
输入描述:
键盘输入一个长度为len(1 <= len < 30)的字符串,再输入一个正整数 m(1 <= m <= len)
输出描述:
输出复制的新字符串
#include <iostream>
using namespace std;
int main() {
char str[30] = { 0 };
cin.getline(str, sizeof(str));
int m;
cin >> m;
// write your code here......
//没有用指针的方案
int len=sizeof(str)/sizeof(char);
char str2[30];
int k=0;
for(int i=m-1;i<len;i++)
{
str2[k++]=str[i];
}
cout<<str2<<endl;
//使用指针的方法
char copystr[30]={0};
char *p=str+m-1;
char *q=copystr;
while(*p != '\0'){ //直到字符串结果
*q = *p; //复制
p++;; //两边指针都后移
q++;
}
cout << copystr << endl;
return 0;
}
18. 创建动态数组
描述
键盘输入一个正整数 n,创建大小为 n 的数组(采用动态数组的方式),将数组中的元素初始化为 n、n+1、…、2n - 1。并输出数组中的元素。
输入描述:
键盘输入一个正整数 n
输出描述:
输出数组中的元素,元素和元素之间使用空格隔开
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
// write your code here......
int* p=new int[n];//创建动态数组的语法格式
for(int i=0;i<n;i++){
p[i]=n+i;
}
for(int i=0;i<n;i++){
cout<<p[i]<<" ";
}
return 0;
}
19. 数组元素处理
描述
有一个数组 int arr[n],要求写一个函数:void func(int *p, int n);将数组 arr 中为 0 的元素都移至数组末尾,将非 0 的元素移至开始(保持原来的顺序不变)。
例如:
数组中元素原来是:1 0 3 4 0 -3 5
经过 func 处理后:1 3 4 -3 5 0 0
输入描述:
键盘输入 6 个整数,保存到数组中
输出描述:
经过 func 处理后数组的元素,元素和元素之间使用空格隔开
例如:1 3 4 -3 5 0 0
#include <iostream>
using namespace std;
void func(int* p, int n);
int main() {
int arr[6] = { 0 };
for (int i = 0; i < 6; i++) {
cin >> arr[i];
}
func(arr, 6);
for (int i = 0; i < 6; i++) {
if (i == 5) {
cout << arr[i] << endl;
}
else {
cout << arr[i] << " ";
}
}
return 0;
}
void func(int* p, int n) {
// 此处语法还不够熟练,认为p给定的只是数组的起始地址,函数内不可使用p[i]表示第[i]个位置上的值
int j;
int i=0;
int temp;
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){
if((p[i]==0) && ((p[j])!=0))
{
temp=p[j];
p[j]=p[i];
p[i]=temp;
}
}
}
}
20. 比较字符串的大小(题目开始难起来了)
描述
编写一个函数 int mystrcmp(const char * src, const char * dst),用于比较两个字符串的大小(自己实现strcmp()函数)。要求如果字符串src大于字符串dst返回 1,小于返回 -1,相等返回 0。
输入描述:
键盘录入 2 个长度小于 100 的字符串
输出描述:
输出调用 mystrcmp() 函数返回的结果
算法说明引自以为牛客博主https://www.nowcoder.com/users/100241712
这道题不是比较字符串的长度的大小,而是比较字符串内容的大小,包含对应位置字符、字符串长度。
#include <iostream>
using namespace std;
int mystrcmp(const char* src, const char* dst);
int main() {
char s1[100] = { 0 };
char s2[100] = { 0 };
cin.getline(s1, sizeof(s1));
cin.getline(s2, sizeof(s2));
int ret = mystrcmp(s1, s2);
cout << ret << endl;
return 0;
}
int mystrcmp(const char* src, const char* dst) {
// write your code here......
int len1=sizeof(src)/sizeof(char);
//使用strlen函数更简洁int len1=strlen(src);
int len2=sizeof(dst)/sizeof(char);
int i=0,j=0;
while(i<len1&&j<len2){
if(src[i]<dst[j]){return -1;}
else if(src[i]>dst[j]){return 1;}
else{
i++;
j++;
}
}
if(i<len1){return 1;}
else if(j<len2){return -1;}
else{return 0;}
return 0;
}
21. 两数交换(通过指针实现)
描述
编写一个函数,实现两个整数的交换,要求采用指针的方式实现。
输入描述:
键盘输入2个整数 m 和 n
输出描述:
输出交换后m 和 n 的值,中间使用空格隔开
#include <iostream>
using namespace std;
// write your code here......
void swap(int *p,int *q);
void swapp(int &a, int &b);
int main() {
int m, n;
cin >> m;
cin >> n;
// write your code here......
swap(m,n);
cout << m << " " << n << endl;
return 0;
}
void swap(int *p, int *q)
{
int temp=*p;
*p=*q;
*q=temp;
}
void swapp(int &a, int &b)
{
int temp=a;
a=b;
b=temp;
}
22. 统计字符串中子串出现的次数
string可以进行+的运算,进行字符串拼接,而CString不可以。
string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos,也就是-1。(返回值可以看成是一个int型的数)
string的find()函数用于找出字母在字符串中的位置。
具体介绍
find(str,position) 其中 find()的两个参数:(str:是要找的元素;position:字符串中的某个位置,表示从从这个位置开始的字符串中找指定元素)。可以不填第二个参数,默认从字符串的开头进行查找,返回值为目标字符的位置,当没有找到目标字符时返回npos。
#include <iostream>
#include <string>
using namespace std;
int main() {
char str[100] = { 0 };
char substr[100] = { 0 };
cin.getline(str, sizeof(str));
cin.getline(substr, sizeof(substr));
int count = 0;
// write your code here......
string str1(str);
string str2(substr);
int i=0;
while(str1.find(str2,i)!=-1){//这个函数需要熟记,方便快捷
count++;
cout<<str1.find(str2,i)<<endl;
i=str1.find(str2,i)+1;
// cout<<str1.find(str2,i)<<endl;
}
cout << count << endl;
return 0;
}
23. 统计字符串中各种符号的数量
描述
键盘录入一句话,统计这句话中字母字符、数字字符、空白、标点符号和其它字符的个数。(使用字符函数实现)
输入描述:
键盘输入一个字符串
输出描述:
输出字符串中字母字符、数字字符、空白、标点符号和其它字符的个数。
提示
字符判断函数 作用
isalpha() 判断字符是否是字母(‘a’-‘z’ ‘A’-‘Z’)
isdigit() 判断字符是否是数字
isspace() 判断字符是否是空格、制表符、换行等标准空白
isalnum() 判断字符是否是字母或者数字
ispunct() 判断字符是标点符号
islower() 判断字符是否是小写字母(‘a’-‘z’)
isupper() 判断字符是否是大写字母(‘A’-‘Z’)
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
int main() {
string str;
getline(cin, str);
int whitespace = 0;
int digits = 0;
int chars = 0;
int others = 0;
// write your code here......
int len1=str.length();
for(int i=0;i<len1;i++){
if(isalpha(str[i]))
chars++;
else if(isdigit(str[i]))
digits++;
else if(isspace(str[i]))
whitespace++;
else
others++;
}
cout << "chars : " << chars
<< " whitespace : " << whitespace
<< " digits : " << digits
<< " others : " << others << endl;
return 0;
}
24. 不死神兔
描述
有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第 n 个月的兔子对数为多少?
输入描述:
键盘输入任意一个正整数 n,n 的范围为 [1, 20]
输出描述:
输出第 n 个月兔子的对数
提示
我们有如下计算:
月份 兔子数(对)
第1个月 1对兔子
第2个月 1对兔子
第3个月 2对兔子(第一对生出第二对)
第4个月 3对兔子(第一对生出第三对)
第5个月 5对兔子(第一对生出第四对、第二对生出第五对)
第6个月 8对兔子(第一对生出第六对、第二对生出第七对、第三对生出第八对)
结论:这其实是一个斐波那契数列
技巧:递归调用函数
#include <iostream>
using namespace std;
int getSum(int n);
int main() {
int n;
cin >> n;
cout << getSum(n) << endl;
return 0;
}
int getSum(int n) {
// write your code here......
int sum[n];
sum[0]=1;
sum[1]=1;
if(n==1||n==2)
return 1;
else
{
for(int i=2;i<n;i++)
sum[i]=sum[i-1]+sum[i-2];
return sum[n-1];
}
//case 2
if(n==1||n==2)
return 1;
return getSum(n-1)+getSum(n-2);
}
25. 设计立方体
用类定义实现封装设计
#include <iostream>
using namespace std;
class Cube {
private:
int length,width,height;
// write your code here......
public:
Cube(){}
void setLength(int l){
length=l;
}
void setHeight(int h){
height=h;
}
void setWidth(int w){
width=w;
}
int getLength(){
return length;
}
int getWidth(){
return width;
}
int getHeight(){
return height;
}
int getArea(){
return 2*(length*width+length*height+width*height);
}
int getVolume(){
return height*width*length;
}
};
int main() {
int length, width, height;
cin >> length;
cin >> width;
cin >> height;
Cube c;
c.setLength(length);
c.setWidth(width);
c.setHeight(height);
cout << c.getLength() << " "
<< c.getWidth() << " "
<< c.getHeight() << " "
<< c.getArea() << " "
<< c.getVolume() << endl;
return 0;
}
26. 设计立方体
描述
有圆类(Circle)和点类(Pointer),请在圆类中实现一个 isPointerInCircle方法,该方法传入一个点类对象,判断点和圆的关系,并在该方法中输出。
点类(Pointer):
成员变量:x轴坐标(int x) y轴坐标(int y)
成员方法:成员变量的公共访问方法
圆类(Circle):
成员变量:圆心(Point center) 半径(int radius)
成员方法:成员变量的公共访问方法 判断点和圆关系的方法(isPointerInCircle)
点和圆的关系:
1.点在圆外
2.点在圆上
3.点在圆内
输入描述:
键盘输入两个整数,分别是点的 x 坐标和 y 坐标(圆的参数已经给定)
输出描述:
圆类中实现 isPointInCircle 方法,在该方法中输出点和圆的关系,
如果点在圆外,则输出“out”;
如果点在圆上,则输出“on”;
如果点在圆内,则输出“in”。
#include <iostream>
using namespace std;
// 点类
class Pointer {
private:
int x; // x 坐标
int y; // y 坐标
public:
void setX(int x) {
this->x = x;
}
int getX() {
return x;
}
void setY(int y) {
this->y = y;
}
int getY() {
return y;
}
};
// 圆类
class Circle {
private:
Pointer center; // 圆心
int radius; // 半径
public:
void setCenter(int x, int y) {
center.setX(x);
center.setY(y);
}
void setRadius(int radius) {
this->radius = radius;
}
// write your code here......
void isPointerInCircle(Pointer p){
int x1=p.getX();
int y1=p.getY();
int x2=center.getX();
int y2=center.getY();
int dist=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
if(dist<radius*radius)
{
cout<<"in"<<endl;
}
else if(dist==radius*radius){
cout<<"on"<<endl;
}
else{
cout<<"out"<<endl;
}
}
};
int main() {
// 键盘输入点的坐标
int x, y;
cin >> x;
cin >> y;
// 创建一个点
Pointer p;
p.setX(x);
p.setY(y);
// 创建一个圆
Circle c;
c.setCenter(5, 0);
c.setRadius(5);
// 判断点和圆的关系
c.isPointerInCircle(p);
return 0;
}
26. 利用构造函数对对象进行初始化
概念:
- C++中提供构造函数来处理对象的初始化。构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户调用它,而是在建立对象的时候自动执行。
- 构造函数没有返回值,因此也没有类型,它的作用只是在定义对象实例后自动调用,且只能执行一次,对对象进行初始化,使得程序员编程更加便捷。一般声明为public。
- 可以用类的一个对象去初始化另一个对象,使得被初始化对象不必自动调用构造函数。
- 也可以使用带参数的构造函数进行初始化。
- 构造函数中的初始化可以用赋值语句实现也可以用参数初始化表实现,例如:
Box::Box(int h, int w):height(h),width(w){}
延伸:
- 构造函数的重载:为对象提供不同的初始化方法。重载规则和定义不变,系统根据重载的多个构造函数的呈现形式不同进行区分。
- 默认构造函数(default constructor) :通过实参传递或指定默认值,默认值应该在声明构造函数时指定默认值。一个类只能有一个默认构造函数。
- 有构造函数就会有析构函数,用于释放对象占用的空间。对于static局部对象或是全局对象,需要在相应进程结束后才会被系统自动释放,对于使用new运算符动态创建的对象,在用delete加以释放之前需要调用该对象的析构函数。析构函数不可以被重载,一个类对象可以有多个构造函数但是只能有一个析构函数。
- 构造函数与析构函数必定是配对的,先构造的后析构,后构造的先析构,这与建立一个简单结构体的符号内联配对是一样的逻辑
题目描述
现有一个人类(Person),成员变量:姓名(string name)和年龄(int age),请给 Person 添加一个支持两个参数的构造函数,并对姓名和年龄两个成员进行初始化。
#include <iostream>
#include <string>
using namespace std;
// Person类
class Person {
public:
string name; // 姓名
int age; // 年龄
// write your code here......
Person(string x,int y){
age=y;
name=x;
}
void showPerson() {
cout << name << " " << age << endl;
}
};
int main() {
string name;
int age;
cin >> name;
cin >> age;
Person p(name, age);
p.showPerson();
return 0;
}
27. 浅拷贝与深拷贝
#include <iostream>
#include <cstring>
#pragma warning(disable : 4996)
using namespace std;
class Person {
public:
char* name; // 姓名
int age; // 年龄
Person(const char* name, int age) {
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
this->age = age;
}
// write your code here......
Person(const Person& p){//拷贝构造函数
this->name=new char[strlen(p.name)+1];
strcpy(this->name,p.name);
this->age=p.age;
}
void showPerson() {
cout << name << " " << age << endl;
}
~Person() {
if (name != nullptr) {
delete[] name;
name = nullptr;
}
}
};
int main() {
char name[100] = { 0 };
int age;
cin >> name;
cin >> age;
Person p1(name, age);
Person p2 = p1;
p2.showPerson();
return 0;
}
28. 友元全局函数
#include <iostream>
using namespace std;
class Person {
// write your code here......
friend void showAge(Person& );
public:
Person(int age) {
this->age = age;
}
private:
int age;
};
void showAge(Person& p) {
cout << p.age << endl;
}
int main() {
Person p(10);
showAge(p);
return 0;
}
29. 友元全局函数
描述
有一个时间类(Time),成员变量有:小时(hours)、分钟(minutes),补充 Time 类的代码,重载加号运算符,使得程序能够正确运行。
输入描述:
键盘输入两个正整数,分别为小时 h 和分钟 m。要求分钟 m 范围为 0 - 59
输出描述:
输出两个 Time 对象(t1 和 t2)相加后的时间结果,通过调用 show() 输出。
解析
类因为一般包含了多个成员变量,甚至包含了不同类型的成员变量,一般的运算符都不能再用了,只能通过重载的方式使用,比如加法运算,编译器不知道该怎么加,是只加小时还是只加分钟,还是全部加起来,而如果换一个类又该怎么加。于是C++提供了符号重载,通过自己写一个函数来表示这个符号该怎么运算。
运算符一般包含单目运算符、双目运算符合三目运算符,因此重载的函数一般形容opertator运算符,返回的东西一般就是这个类的变量实例,这个很好理解,我1+1返回的肯定也是整型int(比较判断类符号除外)。然后是函数的参数,单目运算符就操作这个类本身,无参数,双目运算符操作这个类和另一个实例,三目以此类推。
因此本题要重载的加法运算符,返回值是这个类及Time,参数只有一个,于是写作Time operator+(Time& p),这个p就是传入的要和这个类的元素相加的实例。我们依照时间的加法,将二者的小时数相加,分钟数相加的超过60的部分(整数除法)再加到小时里去,然后分钟数相加的余数加到分钟数,最后返回Time实例的和就行了。
(摘自牛客网https://www.nowcoder.com/users/397721558)
#include <iostream>
using namespace std;
class Time {
public:
int hours; // 小时
int minutes; // 分钟
Time() {
hours = 0;
minutes = 0;
}
Time(int h, int m) {
this->hours = h;
this->minutes = m;
}
void show() {
cout << hours << " " << minutes << endl;
}
// write your code here......
};
int main() {
int h, m;
cin >> h;
cin >> m;
Time t1(h, m);
Time t2(2, 20);
Time t3 = t1 + t2;
t3.show();
return 0;
}
30. 子类中调用父类构造
描述
有父类 Base,内部定义了 x、y 属性。有子类 Sub,继承自父类 Base。子类新增了一个 z 属性,并且定义了 calculate 方法,在此方法内计算了父类和子类中 x、y、z 属性三者的乘积。请补全子类构造方法的初始化逻辑,使得该计算逻辑能够正确执行。
输入描述:
三个整数:x, y, z
输出描述:
三个整数的乘积:xyz
#include <iostream>
using namespace std;
class Base {
private:
int x;
int y;
public:
Base(int x, int y) {
this->x = x;
this->y = y;
}
int getX() {
return x;
}
int getY() {
return y;
}
};
class Sub : public Base {
private:
int z;
public:
Sub(int x, int y, int z) : Base(x,y) {
// write your code here
this->z=z;
}
int getZ() {
return z;
}
int calculate() {
return Base::getX() * Base::getY() * this->getZ();
}
};
int main() {
int x, y, z;
cin >> x;
cin >> y;
cin >> z;
Sub sub(x, y, z);
cout << sub.calculate() << endl;
return 0;
}
31. 重写子类计算逻辑
转载牛客图片:
#include <iostream>
using namespace std;
class Base {
private:
int x;
int y;
public:
Base(int x, int y) {
this->x = x;
this->y = y;
}
int getX() {
return x;
}
int getY() {
return y;
}
void calculate() {
cout << getX() * getY() << endl;
}
};
class Sub : public Base {
// write your code here......
public:
Sub(int x, int y):Base(x,y){}//子类完全继承了父类的成员变量,我们对其初始化直接调用父类的构造函数
void calculate(){
if(Base::getY()==0)
cout<<"Error"<<endl;
else
cout<<Base::getX()/Base::getY()<<endl;
}
};
int main() {
int x, y, z;
cin >> x;
cin >> y;
Sub sub(x, y);
sub.calculate();
return 0;
}
32. 多态实现计算器功能
33. 迭代器遍历容器
描述
键盘输入 5 个整数,将这些数据保存到 vector 容器中,采用正向迭代器和反向迭代器分别遍历 vector 中的元素并输出。
输入描述:
输入 5 个整数
输出描述:
使用正向迭代器和反向迭代器分别遍历输出 vector 中的元素,元素之间使用空格隔开,两次遍历之间换行。
#include <iostream>
// write your code here......
#include <vector>
using namespace std;
int main() {
// write your code here......
vector<int> v;
int a;
while(cin>>a)
v.push_back(a);
vector<int>::iterator iter = v.begin();//迭代器指向vector第一个位置
while(iter!=v.end()){//从第一个位置遍历到尾
cout<<*iter<<" ";//输出
iter++;
}
cout<<endl;//换行
while(iter!=v.begin()){
iter--;
cout<<*iter<<" ";
}
cout<<endl;
return 0;
}
34. 智能排队系统
STL容器知识应用
描述
请设计一个排队程序,用户有普通客人和 VIP 客人之分,VIP 客人不排队(即 VIP 客人在队列头部),请将已有的guest1和guest2放入队列中(guest1排在guest2前),并将VIP客人新增至队列头部。
输入描述:
无
输出描述:
VIP客人姓名 guest1姓名 guest2姓名(每个客人的名字用空格隔开)
#include <iostream>
#include <deque>
using namespace std;
class Guest {
public:
string name;
bool vip;
Guest(string name, bool vip) {
this->name = name;
this->vip = vip;
}
};
int main() {
Guest guest1("张三", false);
Guest guest2("李四", false);
Guest vipGuest("王五", true);
deque<Guest> deque;
// write your code here......
//对于这种队列,要将guest1、2从队尾入队
deque.push_back(guest1);
deque.push_back(guest2);
//vip客户要从对头入队
deque.push_front(vipGuest);
for (Guest g : deque) {
cout << g.name << " ";
}
return 0;
}
35. 去除字符串中重复的数字
描述
从键盘获取一串字符串,要求去除重复的字符,请使用 set 解决。
输入描述:
键盘输入任意字符串
输出描述:
输出去重后的内容(直接按 set 的默认顺序输出字符即可)
#include <iostream>
// write your code here......
#include <set>
using namespace std;
int main() {
char str[100] = { 0 };
cin.getline(str, sizeof(str));
// write your code here......
set<char> s;//STL集合容器,相同的元素在set中只保留一次,且会依赖于红黑树自动排序
for(int i=0;str[i]!='\0';i++)
s.insert(str[i]);//将字符加入到set中,这样它会自动去重排序
for(auto iter=s.begin();iter!=s.end();iter++)//用迭代器遍历set,像cpp48一样依次输出
cout<<*iter;
return 0;
}
36. 统计字符串中各字母字符对应的个数
描述
键盘输入一个字符串,统计字符串中各个字母字符的个数。例如:键盘输入"Hello World!",上述字符串中各个字母字符的出现的次数为:
H:1
e:1
l:3
o:2
W:1
r:1
d:1
要求使用map实现,键的排序使用map默认排序即可。
#include <iostream>
// write your code here......
#include <map>
using namespace std;
int main() {
char str[100] = { 0 };
cin.getline(str, sizeof(str));
// write your code here......
map<char,int>maps;
for(int i=0;str[i]!='\0';i++)//改变了原来key和value的类型和顺序
{
if(isalpha(str[i]))//判断是否是字符
{
maps[str[i]]++;
//1.maps[str[i]]++等价于maps[str[i]]=maps[str[i]]+1
//2.maps[str[i]]++指的是取出map对应key的value值再累加
}
}
for(auto it=maps.begin();it!=maps.end();it++)
{
cout<<it->first<<":"<<it->second<<endl;
}
return 0;
}
37. STL算法应用
描述
键盘输入 5 个整数,使用 vector 进行存储,使用 STL 排序算法对元素进行排序(从大到小),再使用 STL 遍历算法输出元素。(元素和元素之间使用空格隔开)
输入描述:
键盘输入 5 个整数
输出描述:
输出排序后的元素,元素和元素之间使用空格隔开
#include <functional>
#include <iostream>
#include <vector>
// write your code here......
#include <algorithm>//因为用了sort()函数
using namespace std;
void print(int x){
cout<<x<<" ";
}
int main() {
int num;
vector<int> v;
for (int i = 0; i < 5; i++) {
cin >> num;
v.push_back(num);
}
// write your code here......
sort(v.begin(),v.end(),greater<int>());//内置类型的由大到小排序
for_each(v.begin(),v.end(),print);
return 0;
}
38. 统计字符串中各种字符的个数
图片摘自牛客题解评论区 https://www.nowcoder.com/users/100241712
简单无虐
39. 计算个人所得税
使用STL容器替代case等循环体的使用,同时满足排序要求。
题目本身很好理解,已经帮读者划分成了一个分段函数。
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;
class Employee {
private:
string name;
double salary;
public:
//构造函数
Employee(string name,double salary){
this->name=name;
this->salary=salary;
}
//获取名字
string getName(){
return name;
}
//获取薪水
double getSalary(){
return salary;
}
};
//重载比较,按薪水从大到小
bool cmp(Employee& e1,Employee& e2){
return e1.getSalary()>e2.getSalary();
}
void print(Employee& e){
//个人所得税
double tax=0.0;
//全月应纳税所得额
double t=e.getSalary()-3500;
//按表中所给的范围,分别进行计算
if(t<=0){
//小于0,不需要扣税
}
//其它情况,按所给公式及表中数据计算
else if(t>0&&t<=1500){
tax=t*0.03-0;
}
else if(t>1500&&t<=4500){
tax=t*0.10-105;
}
else if(t>4500&&t<=9000){
tax=t*0.20-555;
}
else if(t>9000&&t<=35000){
tax=t*0.25-1005;
}
else if(t>35000&&t<=55000){
tax=t*0.30-2755;
}
else if(t>55000&&t<=80000){
tax=t*0.35-5505;
}
else{
tax=t*0.45-13505;
}
//设置精度
cout<<fixed<<setprecision(1);
cout<<e.getName()<<"应该缴纳的个人所得税是:"<<tax<<endl;
}
int main() {
//新建三个Employee对象
Employee e1("张三",6500);
Employee e2("李四",8000);
Employee e3("王五",100000);
vector<Employee> vec;
//添加到容器
vec.push_back(e1);
vec.push_back(e2);
vec.push_back(e3);
//按工资从大到小排序
sort(vec.begin(),vec.end(),cmp);
//输出个人所得税
for_each(vec.begin(),vec.end(),print);
return 0;
}
40. 实现简单计算器功能
计算过程动态显示图
#include <iostream>
#include <cstring>
#include <strings.h>
using namespace std;
int main() {
char str[100] = { 0 };
cin.getline(str, sizeof(str));
// write your code here......
char* msg[30]={str,nullptr};
int i=0;
//将原字符串按空格分割 运算方式忽略大小写,不用担心
while((msg[i]=strtok(msg[i]," "))&&++i);
//存储运算符
char* op=msg[0];
//存储整数1,利用atoi将字符串类型转为整型
int num1=atoi(msg[1]);
//存储整数2
int num2=atoi(msg[2]);
if(strcasecmp(op, "add")==0){
cout<<num1+num2<<endl;
}
else if(strcasecmp(op, "sub")==0){
cout<<num1-num2<<endl;
}
else if(strcasecmp(op, "mul")==0){
cout<<num1*num2<<endl;
}
else if(strcasecmp(op, "div")==0){
if(num2==0){
cout<<"Error"<<endl;
}
else{
cout<<num1/num2<<endl;
}
}
return 0;
}
附上一种简单朴实的从字符串中分割字符子串的方法
string op="";
string num1="";
string num2="";
int space=0;
for(int i=0;str[i]!='\0';i++){//对于string型的变量,这几乎成为固定的遍历格式 如果使用sizeof(str)/sizeof(char)计数结果会出错,我觉得与字符串结尾
if(str[i]==' '){
space++;
continue;
}
else if(space==0)
{
op+=str[i];
}
else if(space==1){
num1+=str[i];
}
else if(space==2){
num2+=str[i];
}
}
int x=stoi(num1);
int y=stoi(num2);
if(strcasecmp(op.c_str(), "add")==0){
cout<<x+y<<endl;
}
以上两种分割字符串的差别:
- 为什么在方法一中使用char型创建变量?
- 使用strcasecmp函数时方法之间的区别?
- 为什么方法一中要使用指针型定义方式?
41.十进制整数转十六进制字符串
描述
编写一个函数,传入一个十进制的正整数,将十进制整数转换为十六进制的字符串并返回。(十六进制字符串中的字母全部大写)
输入描述:
键盘输入一个十进制的正整数
输出描述:
输出该十进制整数转换后的十六进制字符串
#include <iostream>
#include <string>
#include<bits/stdc++.h>
using namespace std;
string toHexString(int n);
int main() {
int n;
cin >> n;
string hexStr = toHexString(n);
cout << hexStr << endl;
return 0;
}
string toHexString(int n) {
// write your code here......
string hex="";
while(n!=0){
int mod=n%16;
if(mod>=0&&mod<=9){
char c=mod+'0';
hex+=c;//虽然上一题有用过,但我仍然觉得这个东西很神奇
}
else {
char c=mod-10+'A';
hex+=c;
}
n=n/16;
}
reverse(hex.begin(),hex.end());//字符串反转函数
return hex;
}
42.字符的个数
描述
输入一个只包含’a’,‘b’,‘c’的字符串,问’a’,‘b’,‘c’分别出现了多少次。
输入描述:
输入一个只包含’a’,‘b’,‘c’的字符串
输出描述:
输出用空格隔开的三个整数分别表示’a’,‘b’,'c’出现了多少次
很简单的一道基础入门题
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
cin>>s;
// write your code here......
int flaga=0;
int flagb=0;
int flagc=0;
for(int i=0;s[i]!='\0';i++)//对于string型的变量,这几乎成为固定的遍历格式
{
if(s[i]=='a'){
flaga++;
}
else if(s[i]=='b'){
flagb++;
}
else if(s[i]=='c'){
flagc++;
}
}
cout<<flaga<<" "<<flagb<<" "<<flagc<<endl;
//cout<<sizeof(s)/sizeof(string)<<endl;
//结果是1,也不是我们想要的
//sizeof(s)/sizeof(string)只能在主串与子串变量类型相同的情况下才可以使用
return 0;
}
分享一个C++中字符串反转的帖子,提供了三种方式
https://blog.csdn.net/Szu_AKer/article/details/52422191
43.创建动态二维数组
创建动态二维数组的基本概念可移步至:
https://blog.csdn.net/weixin_42148873/article/details/102869022
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int **arr=new int*[n];
for(int i=0;i<n;i++){
arr[i]=new int[n];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j]=i+j;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
for(int i=0;i<n;i++){
delete[] arr[i];
}
arr=NULL;
return 0;
}
最直接最基础的方法大概就是如上所述,但是将动态二维数组看成一个特殊的一维数组之后,一切变得不同了。如果不能理解,那么熟悉python和Pytorch中张量理论的人应当更能体会这其中的奥秘。于是,简洁有效的操作可以更改为:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
// write your code here......
int *p=new int[n*n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
p[i+j]=i+j;
cout<<p[i+j]<<" ";
}
cout<<endl;
}
return 0;
}
44.编写函数实现字符串翻转(引用方式)
上面才用到现成的库函数,现世报就来了,那么就开始敲代码吧。☹
#include<bits/stdc++.h>
using namespace std;
// write your code here......
void reverse_string(string &s){
int n=s.length();
for(int i=0;i<n/2;i++){
char temp=s[n-1-i];
s[n-1-i]=s[i];
s[i]=temp;
}
}
int main(){
string s;
getline(cin,s);
// write your code here......
//使用引用的方式其实是防止传递实参会输出相同的结果但是原始字符串并没有更改
//本题的目的是把原始字符串有效更改
//真实笔试环境中如果改掉要求只保证结果正确,会被识别出来吗??
reverse_string(s);
//下面的这个方案二无法保证测试用例通过率100%,不清楚具体什么原因
// int n=s.length();
// string s2="";
// int flag=n-1;
// for(int i=0;i<n;i++){
// s2[i]=s[flag--];
// cout<<s2[i];
// }
cout<<s;
return 0;
}
45.比较两个长方形面积的大小
描述
给出两个长方形的长和宽,实现长方形类的一个比较面积大小的方法,判定哪个面积大。
输入描述:
输入4个整数,前两个表示第一个长方形的长和宽,后两个表示第二个长方形的长和宽。
输出描述:
如果前者面积大,输出1,否则输出0。
#include<bits/stdc++.h>
using namespace std;
class rectangle{
private:
int length,width;
public:
void set(int x,int y){
length=x;
width=y;
}
int getlength(){
return length;
}
int getwidth(){
return width;
}
int area(){
return length*width;
}
void compare(rectangle a){
// write your code here......
int s1;
int s2;
s1=length*width;
s2=a.area();
if(s1>s2)
cout<<1<<endl;
else
cout<<0<<endl;
}
};
int main(){
int l1,w1,l2,w2;
cin>>l1>>w1>>l2>>w2;
rectangle a,b;
a.set(l1,w1);
b.set(l2,w2);
a.compare(b);
return 0;
}
46. 数组类的构造函数
描述
现在有一个数组类,请实现它的构造函数。
输入描述:
第一行一个整数n,表示数组的大小。
第二行n个整数,表示数组。
输出描述:
输出这个数组。
#include<bits/stdc++.h>
using namespace std;
class Array{
private:
int n;//数组大小
int *a;//数组
public:
// write your code here......
Array(){
cin>>n;
a=new int[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
}
~Array(){
delete []a;
}
void show(){
for (int i=0;i<n;i++) cout<<a[i]<<' ';
}
};
int main(){
Array a;
a.show();
return 0;
}
47. 数组类的拷贝构造函数
描述
现有一个数组类Array,请你设计一个正确的拷贝构造函数。
输入描述:
第一行一个整数n,表示数组的大小。
第二行n个整数,表示数组。
输出描述:
输出这个数组。
#include<bits/stdc++.h>
using namespace std;
class Array{
private:
int n;//数组大小
int *a;//数组
public:
Array(){
cin>>n;
a=new int [n];
for (int i=0;i<n;i++) cin>>a[i];
}
~Array(){
delete []a;
}
int getlen(){
return n;
}
int get(int i){
return a[i];
}
// write your code here......
Array(Array &array){
delete[] a;
n=array.getlen();
a=new int[n];
for(int i=0;i<n;i++){
a[i]=array.get(i);
}
}
void show(){
for (int i=0;i<n;i++) cout<<a[i]<<' ';
}
};
int main(){
Array a;
Array b=a;
b.show();
return 0;
}
48. 友元类举例
#include<bits/stdc++.h>
using namespace std;
class phone{
// write your code here......
friend class myphone;
private:
int price;
public:
phone(int x){
price=x;
}
};
class myphone{
private:
phone a;
public:
myphone(int x):a(x){
}
int getprice(){
return a.price;
}
};
int main(){
int p;
cin>>p;
myphone a(p);
cout<<a.getprice();
return 0;
}
49. 重载小于号
描述
有一个时间类(Time),成员变量有:小时(hours)、分钟(minutes),补充 Time 类的代码,重载小于号运算符,使得程序能够正确运行。
输入描述:
键盘输入两个整数,分别为小时h和分钟m,其中0≤m<60。
输出描述:
比较输入时间与6小时6分钟的大小,若输入时间较小则输出"yes",否则输出"no"。
#include <iostream>
using namespace std;
class Time {
public:
int hours; // 小时
int minutes; // 分钟
Time() {
hours = 0;
minutes = 0;
}
Time(int h, int m) {
this->hours = h;
this->minutes = m;
}
void show() {
cout << hours << " " << minutes << endl;
}
// write your code here......
bool operator <(Time t)
{
if((hours<t.hours)||(hours==t.hours)&&(minutes<t.minutes))){
return true;
}
return false;
}
};
int main() {
int h, m;
cin >> h;
cin >> m;
Time t1(h, m);
Time t2(6, 6);
if (t1<t2) cout<<"yes"; else cout<<"no";//对两个类对象进行比较,因此需要定义类之间的操作符返回值
//常规的只有两个数据型变量之间比较大小
return 0;
}
这道题其实反应了在程序当中已有的加减乘除操作符在底层其实是如何实现的。
50. 构建长方体类
关于子类继承父类的练习题
#include<bits/stdc++.h>
using namespace std;
class rectangle{
private:
int length,width;
public:
rectangle(int x,int y){
length=x;
width=y;
}
void set(int x,int y){
length=x;
width=y;
}
int area(){
return length*width;
}
};
class cuboid:public rectangle{
private:
int height;
public:
// write your code here...
//继承基类的属性
//构造函数继承基类
cuboid(int x, int y, int z):rectangle(x, y){
this->height=z;
}
int getvolume(){
return this->area()*this->height;
}
};
int main(){
int x,y,z;
cin>>x>>y>>z;
cuboid a(x,y,z);
cout<<a.getvolume();
return 0;
}
51. 求长方体表面积
#include<bits/stdc++.h>
using namespace std;
class rectangle{
private:
int length,width;
public:
rectangle(int x,int y){
length=x;
width=y;
}
void set(int x,int y){
length=x;
width=y;
}
int getlength(){
return length;
}
int getwidth(){
return width;
}
int area(){
return length*width;
}
};
class cuboid:public rectangle{
private:
int height;
public:
// write your code here...
//子类的构造函数继承与父类的构造函数,写法:子类名(子类属性):父类名(父类属性){额外属性定义}
cuboid(int x,int y, int z):rectangle(x, y){
this->height=z;
}
int area(){
//注意不能用this->area(),否则调用的是这个函数,要用this->rectangle::area(),明确是父类中的area()函数
return (this->height*this->getwidth()+this->height*this->getlength()+this->rectangle::area())*2;
}
};
int main(){
int x,y,z;
cin>>x>>y>>z;
cuboid a(x,y,z);
cout<<a.rectangle::area()<<'\n'<<a.area();//第一行底面积 第二行表面积
return 0;
}
52. 多态实现求面积体积
#include<bits/stdc++.h>
using namespace std;
class rectangle{
private:
int length,width;
public:
rectangle(int x,int y){
length=x;
width=y;
}
void set(int x,int y){
length=x;
width=y;
}
int getlength(){
return length;
}
int getwidth(){
return width;
}
// write your code here...
//多态关键字virtual,父类声明,也可以实现(面积)
virtual int getval(){
return this->length*this->width;
}
};
class cuboid:public rectangle{
private:
int height;
public:
cuboid(int x,int y,int z):rectangle(x,y){
height=z;
}
// write your code here...
virtual int getval(){
// return this->rectangle::getval()*this->height;
return this->height*this->getlength()*this->getwidth();
}
};
int main(){
int x,y,z;
cin>>x>>y>>z;
cuboid a(x,y,z);
rectangle b(x,y);
rectangle *p=&b;
cout<<p->getval()<<'\n';
p=&a;
cout<<p->getval();
return 0;
}
53. 迭代器遍历set
描述
键盘输入 5 个整数,将这些数据保存到set中,采用迭代器正向遍历set中的元素并输出。
输入描述:
一行输入5个整数。
输出描述:
迭代器正向遍历set中的元素并输出,输出一行,元素用空格隔开。
#include<bits/stdc++.h>
using namespace std;
int main(){
set<int>s;
// write your code here......
for(int i=0;i<5;i++)
{
int temp=0;
cin>>temp;
s.insert(temp);//插入元素
}
for(set<int>:: iterator it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
return 0;
}
54. 最后k个元素
描述
给出一个包含n个整数的数组a,使用vector实现倒序输出数组的最后k个元素。
输入描述:
第一行两个整数n,k。(0<k≤n)
第二行n个整数表示数组a。
输出描述:
输出一行k个用空格隔开的整数。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
vector<int>a;
// write your code here......
cin>>n>>k;
for(int i=0,x;i<n;i++){
while(cin>>x)
{
a.push_back(x);
}
}
int i=0;
for(vector<int>::iterator it=a.end()-1;it!=a.begin(),i<k;it--,i++){
cout<<*it<<' ';
}
cout<<endl;
return 0;
}
55. 查找
关于迭代器在程序中所起的作用有哪些?
对你来说,迭代器不只是迭代的功能,还有些什么有趣的功能呢?
#include<bits/stdc++.h>
using namespace std;
int main(){
set<int>s;
//write your code here......
int n,m,x,a;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>a;
s.insert(a);//有序存储不重复
}
while(m--){
cin>>x;
auto it=s.upper_bound(x);
if(it==s.end()){
cout<<-1<<endl;
}
else{
cout<<*it<<endl;
}
}
return 0;
}
56. 判断元素是否出现
map,vector, set三个东西还不熟悉,有点儿意思,需要整理学习
题目内容
描述
给出一个大小为n的数组a,有m次询问,每次询问给出一个x,你需要判断x是否在数组a中出现,如果出现了,输出"yes",否则输出"no"。
要求使用map实现。
输入描述:
第一行两个整数n,m。
第二行n个整数表示数组a。
接下来m行,每行一个整数x。
输出描述:
对每个询问,输出一行表示答案。
#include<bits/stdc++.h>
#include<map>
using namespace std;
int main(){
//write your code here......
map<int,string>ma;
map<int,string>::iterator it;
int n,m,x;
cin>>n>>m;
while(n--){
cin>>x;
ma.insert(pair<int, string>(x,"yes"));
}
while(m--){
cin>>x;
it=ma.find(x);
if(it==ma.end())
cout<<"no"<<endl;
else
cout<<"yes"<<endl;
}
return 0;
}
57. 找到数组里的第k大数(C++)
描述
给出一个包含n个整数的数组a,使用vector存储。用STL算法实现输出数组的第k大数。
输入描述:
第一行两个整数n,k。(1≤k≤n)
第二行n个整数表示数组a。
输出描述:
输出一个数表示答案。
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
int main(){
int n,k;
vector<int>a;
// write your code here......
cin>>n>>k;
int i,num;
for(int i=0;i<n;i++)
{
cin>>num;
a.push_back(num);//在使用vector存放这些数据的时候,要从队尾输入,它会依次排放
//还没具体学习,不太清楚
}
sort(a.begin(),a.end());//要类比python等其他语言,C++中肯定也有封装好的常用函数,省去自己排序的环节事情就变得简单很多,要会调用库函数!
//在没有明确限制的情况下要灵活使用
cout<<a[k-1];
return 0;
}
总结
以上虽然都是一些简单的问题,但是深挖下去其实有一些细节内容需要注意。这些在黑马视频教程中也有所体现: