C++_第五周做题总结_构造与析构

id:31 A.Point(类与构造)

题目描述

下面是一个平面上的点的类定义,请在类外实现它的所有方法,并生成点测试它。

class Point
{double x, y;
public:Point(); // 缺省构造函数,给x,y分别赋值为0Point(double x_value, double y_value); // 有参构造函数double getX(); // 返回x的值double getY();void setX(double x_value); // 设置x的值void setY(double y_value);double dis(Point p); // 计算当前点到参数点的距离
};

输入

测试数据的组数 t

第一组测试数据点p1的x坐标 第一组测试数据点p1的y坐标 第一组测试数据点p2的x坐标 第一组测试数据点p2的y坐标

输出

输出p1到p2的距离,保留两位小数。详情参考输出样例。

在C++中,输出指定精度的参考代码如下:

#include <iostream>#include <iomanip> //必须包含这个头文件using namespace std;void main( ){ double a =3.14;cout<<fixed<<setprecision(3)<<a<<endl;  //输出小数点后3位}

输入样例

2
1 2 3 4
-1 0.5 -2 5

输出样例

Distance of Point(1.00,2.00) to Point(3.00,4.00) is 2.83
Distance of Point(-1.00,0.50) to Point(-2.00,5.00) is 4.61

题解

  • 首先分析class类,Point(); // 缺省构造函数,给x,y分别赋值为0,这行代码的意思是,当使用Point类型定义一个变量且后面不跟任何参数时,会默认的执行这个函数,即为x, y分别赋值为0;Point(double x_value, double y_value); // 有参构造函数,若用Point类型定义一个变量,且这个变量后面带参数,即会给这个变量的成员x和y赋括号里参数的值;double getX(); // 返回x的值,当调用这个函数时,我们的目的是得到Point类型的变量的成员x的值;同理double getY();这个代码的功能也是一样的;void setX(double x_value); // 设置x的值,当调用这个函数时,会将调用这个函数的变量的x的值改变为参数的值;同理void setY(double y_value);double dis(Point p); // 计算当前点到参数点的距离,在这个函数中,我们还要额外定义三个变量,一个用来存储两个点之间横坐标距离之差,一个用来存储纵坐标距离之差,还有一个用来存储计算得到的距离并返回,注意,在计算两个点之间的距离时,我们需要使用到两个点的横纵坐标的值,故会引起怎么引用的问题,我们需要用一个参数来调用这个计算两个点之间的距离的函数,故完成了一个点的调用,然后这个函数是带有参数的,把另一个点当作参数调用,则完成了两个点的调用,在这个函数中,x和y是调用这个函数的变量的成员,而怎么调用另一个变量的横纵坐标呢,则需要使用get函数,这个另一个点调用这个函数,然后会返回这个变量的横纵坐标,则实现了两个点的横纵坐标的调用
  • 然后来看主函数的功能,在主函数中,我们需要定义测试组数和遍历变量,一个用于接收返回距离两点间答案的变量,然后定义一个Point类型的变量,这个变量会执行一次缺省构造函数,还要定义四个变量用于接收输入进来的两个点的横纵坐标的值
  • 一个for循环,遍历完全组的两点,输入两个点的横纵坐标,然后定义一个Point类型的变量,带两个参数,将这两个参数的值赋到这个变量的横纵坐标变量,再调用类里边的set函数,将另外两个横纵坐标赋值到这个调用的变量的横纵坐标变量上,为什么要怎么麻烦,我也不懂,因为题目要求用上所有的类里边的函数,只能这样
  • 最后就是按着输出样例的格式输出距离

代码实现

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;class Point
{double x, y;
public:Point(); // 缺省构造函数,给x,y分别赋值为0Point(double x_value, double y_value); // 有参构造函数double getX(); // 返回x的值double getY();void setX(double x_value); // 设置x的值void setY(double y_value);double dis(Point p); // 计算当前点到参数点的距离
};Point::Point()
{x = 0;y = 0;
}Point::Point(double x_value, double y_value)
{x = x_value;y = y_value;
}double Point::getX()
{return x;
}double Point::getY()
{return y;
}void Point::setX(double x_value)
{x = x_value;
}void Point::setY(double y_value)
{y = y_value;
}double Point::dis(Point p)
{double result, dx, dy;dx = x - p.getX();dy = y - p.getY();result = sqrt(dx * dx + dy * dy);return result;
}int main()
{int t, i;double ans, p1x, p1y, p2x, p2y;Point p2;cin >> t;for (i = 0; i < t; i++){cin >> p1x >> p1y >> p2x >> p2y;Point p1(p1x, p1y);p2.setX(p2x);p2.setY(p2y);ans = p1.dis(p2);cout << "Distance of Point(" << fixed << setprecision(2) << p1.getX() << "," << fixed << setprecision(2) << p1.getY() << ") to Point(" << fixed << setprecision(2) << p2.getX() << "," << fixed << setprecision(2)<< p2.getY() << ") is ";cout << fixed << setprecision(2) << ans << endl;}return 0;
}

id:32 B.Date(类与构造)

题目描述

下面是一个日期类的定义,请在类外实现其所有的方法,并在主函数中生成对象测试之。

class Date
{int year, month, day;
public:Date(); // 缺省构造函数Date(int y, int m, int d); // 带参构造函数int getYear(); // 返回当前日期的年份int getMonth();int getDay();void setDate(int y, int m, int d); // 按参数重设日期的值void print(); // 按格式输出当前日期的年、月、日void addOneDay(); // 在当前日期上加一天
};

注意,在判断明天日期时,要加入跨月、跨年、闰年的判断

例如9.月30日的明天是10月1日,12月31日的明天是第二年的1月1日

2月28日的明天要区分是否闰年,闰年则是2月29日,非闰年则是3月1日

输入

测试数据的组数t

第一组测试数据的年 月 日

要求第一个日期的年月日初始化采用构造函数,第二个日期的年月日初始化采用setDate方法,第三个日期又采用构造函数,第四个日期又采用setDate方法,以此类推。

输出

输出今天的日期

输出明天的日期

输入样例1

4
2012 1 3
2012 2 28
2012 3 31
2012 4 30

输出样例1

Today is 2012/01/03
Tomorrow is 2012/01/04
Today is 2012/02/28
Tomorrow is 2012/02/29
Today is 2012/03/31
Tomorrow is 2012/04/01
Today is 2012/04/30
Tomorrow is 2012/05/01

输入样例2

4
2014 1 3
2014 2 28
2014 3 31
2014 4 30

输入样例3

3
2000 2 29
2014 3 31
2014 12 31

提示

C++中设置填充字符的代码参考如下:

cout << setfill('0') << setw(2) << month; //设置宽度为2,前面补'0'

需要头文件#include <iomanip>

题解

  • 首先来分析日期类,Date(); // 缺省构造函数,用来初始化类里面的年月日;Date(int y, int m, int d); // 带参构造函数,用来给年月日赋参数的值,int getYear(); // 返回当前日期的年份,通过调用这个函数,我们可以得到调用这个函数的变量的年份的值;同理int getMonth(); int getDay();这两行的代码功能相同;void setDate(int y, int m, int d); // 按参数重设日期的值将日期的值设为参数的值,这个函数可以用在初始化一个Date类型的变量中;void print(); // 按格式输出当前日期的年、月、日,这个函数只用于输出当天日期的值,即,当输入一个日期时,便马上调用这个函数输出这个日期的值;void addOneDay(); // 在当前日期上加一天,这个函数用来计算输入的日期的下一天的日期
  • void addOneDay(); // 在当前日期上加一天,在这个函数中,我们先用日作为if语句判断的条件,然后再判断月份,最后判断年份;具体来数,我们把判断的条件划分为,是否是28号,29号,30号和31号这几个特殊的日期,如果是28号的话,再判断其是否是2月份,再判断其是否是闰年,如果是29号的话,判断其是否是二月份,但是不用再判断是否是闰年,如果是30号的话,要分大小月;31号特殊的地方在于要判断他的月份是否是12月,如果是的话要年份加一
  • 然后来看看主函数的功能,需要定义用于存储输入进来的年月日的变量,然后还要定义Date类型的变量,因为需要年月日的成员,在定义这个变量是,程序自动地执行缺省构造函数
  • 然后进行输入,因为题目有要求,所以需要根据不同的输入次数采用不同的方法初始化变量,当输入的次数为奇数次时,采用带参构造函数法,因为此时已经输入了年月日,要把输入进来的年月日传入变量中,随即调用输出函数输出当前的日期,然后调用日期加一函数,计算加一后的日期,然后在主函数中输出加了一天后的日期;如果输入次数为偶数次时,日期的初始化采用setDate方法,即调用这个函数初始化变量,后面的步骤相同

代码实现

#include <iostream>
#include <iomanip>
using namespace std;class Date
{int year, month, day;
public:Date(); // 缺省构造函数Date(int y, int m, int d); // 带参构造函数int getYear(); // 返回当前日期的年份int getMonth();int getDay();void setDate(int y, int m, int d); // 按参数重设日期的值void print(); // 按格式输出当前日期的年、月、日void addOneDay(); // 在当前日期上加一天
};Date::Date()
{year = 1900;month = 1;day = 1;
}Date::Date(int y, int m, int d)
{year = y;month = m;day = d;
}int Date::getYear()
{return year;
}int Date::getMonth()
{return month;
}int Date::getDay()
{return day;
}void Date::setDate(int y, int m, int d)
{year = y;month = m;day = d;
}void Date::print()
{cout << "Today is " << setfill('0') << setw(2) << year << "/" << setfill('0') << setw(2) << month << "/" << setfill('0') << setw(2) << day << endl;
}void Date::addOneDay()
{if (day == 28){if (month == 2){if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) // 是闰年{day++;}else // 不是闰年{day = 1;month++;}}}else if (day == 29){if (month == 2){day = 1;month++;}else{day++;}}else if (day == 30){switch (month){case 1: day++;break;case 3: day++;break;case 4: day = 1;month++;break;case 5: day++;break;case 6: day = 1;month++;break;case 7: day++;break;case 8: day++;break;case 9: day = 1;month++;break;case 10: day++;break;case 11: day = 1;month++;break;case 12: day++;break;}}else if (day == 31){if (month == 12){day = 1;year++;month = 1;}else{day = 1;month++;}}else{day++;}
}int main()
{int t, i, yy, mm, dd;;Date DD;cin >> t;for (i = 0; i < t; i++){cin >> yy >> mm >> dd;if (i % 2 == 0){Date DD0(yy, mm, dd);DD0.print();DD0.addOneDay();cout << "Tomorrow is " << setfill('0') << setw(2) << DD0.getYear() << "/" << setfill('0') << setw(2) << DD0.getMonth() << "/" << setfill('0') << setw(2) << DD0.getDay() << endl;}else{DD.setDate(yy, mm, dd);DD.print();DD.addOneDay();cout << "Tomorrow is " << setfill('0') << setw(2) << DD.getYear() << "/" << setfill('0') << setw(2) << DD.getMonth() << "/" << setfill('0') << setw(2) << DD.getDay() << endl;}}return 0;
}

id:33 C.分数类(类与构造)

题目描述

完成下列分数类的实现:

class CFraction
{
private:int fz, fm;
public:CFraction(int fz_val, int fm_val) ;CFraction add(const CFraction &r);CFraction sub(const CFraction &r);CFraction mul(const CFraction &r);CFraction div(const CFraction &r);int getGCD();   // 求对象的分子和分母的最大公约数void print();
};

求两数a、b的最大公约数可采用辗转相除法,又称欧几里得算法,其步骤为:

  1. 交换a, b使a > b;
  2. 用a除b得到余数r,若r=0,则b为最大公约数,退出.
  3. 若r不为0,则用b代替a, r代替b,此时a,b都比上一次的小,问题规模缩小了;
  4. 继续第2步。

注意:如果分母是1的话,也按“分子/1”的方式输出。

输入

测试数据的组数 t

第一组第一个分数

第一组第二个分数

第二组第一个分数

第二组第二个分数

输出

第一组两个分数的和

第一组两个分数的差

第一组两个分数的积

第一组两个分数的商

第二组两个分数的和

第二组两个分数的差

第二组两个分数的积

第二组两个分数的商

输入样例

3
1/2
2/3
3/4
5/8
21/23
8/13

输出样例

7/6
-1/6
1/3
3/4

11/8
1/8
15/32
6/5

457/299
89/299
168/299
273/184

题解

  • 首先来看CFraction类,CFraction(); // 缺省构造函数,将fz和fm都赋值为1;CFraction(int fz_val, int fm_val); // 带参构造函数,将fz和fm都赋值为参数的值;CFraction add(const CFraction& r);,在这个函数中,要定义整形三个变量,一个用来将分子相加得到的结果存储,一个将新得到的分母进行存储,还要定义一个CFraction类型的变量,定义时要含参,参数即是新的分子分母,这个变量的分子和分母即是得到的新的分子和分母,然后这个新定义的变量调用求最大公约数的函数,将得到的最大公约数的值存储到一个整型变量中,然后更新分子和分母,即是分子和分母约分后的值,再定义一个CFraction类型的变量,也要含参,参数就是更新后的分子分母,作用就是,将参数赋值给这个变量的分子分母,故这个变量就是两个分数相加的结果,返回最后定义的这个CFraction类型的变量;后面的和差积商都是相同的方法;int getGCD(); // 求对象的分子和分母的最大公约数,用到的方法是辗转相除法,需要注意的是,如果出现了负数,我们需要确保这个计算得到的最大公约数的结果,及返回值是正数,所以我们需要判断参数进来的是否是正数;void print();,进行简单的输出即可
  • 在主函数中,我们需要定义四个整型变量,用来存储输入进来的两个分数的分子和分母,还要定义一个char型的变量,用来存储"/",输入两个分数的分子和分母后,定义两个CFraction类型的变量,后面带两个参数,即是要赋值到这个变量的分子和分母的参数,还要定义一个CFraction类型的变量,这个变量用来存储计算后返回的结果,然后这个变量调用输出函数进行计算后得到的结果进行输出,每做完一个计算就调用一次输出函数进行输出

反思

在类函数的实现时,如两个分数的相加,一开始我没有额外的定义一个整形变量来存储计算后的分子分母的值,而是将计算后的值直接更新到调用这个加法函数的变量的分子上,导致后来这个分数的分子已经不是原来输入的分子,即他的值已经改变,所以后面再进行的减法,乘法和除法得到的结果都是错的

代码实现

#include <iostream>
using namespace std;class CFraction
{
private:int fz, fm;
public:CFraction(); // 缺省构造函数CFraction(int fz_val, int fm_val); // 带参构造函数CFraction add(const CFraction& r);CFraction sub(const CFraction& r);CFraction mul(const CFraction& r);CFraction div(const CFraction& r);int getGCD(); // 求对象的分子和分母的最大公约数void print();
};CFraction::CFraction()
{fz = 1;fm = 1;
}CFraction::CFraction(int fz_val, int fm_val)
{fz = fz_val;fm = fm_val;
}CFraction CFraction::add(const CFraction& r)
{int new_fz, new_fm, gcd;new_fz = fz * r.fm + r.fz * fm;new_fm = fm * r.fm;CFraction f(new_fz, new_fm);gcd = f.getGCD();new_fz /= gcd;new_fm /= gcd;CFraction ff(new_fz, new_fm);return ff;
}CFraction CFraction::sub(const CFraction& r)
{int new_fz, new_fm, gcd;new_fz = fz * r.fm - r.fz * fm;new_fm = fm * r.fm;CFraction f(new_fz, new_fm);gcd = f.getGCD();new_fz /= gcd;new_fm /= gcd;CFraction ff(new_fz, new_fm);return ff;
}CFraction CFraction::mul(const CFraction& r)
{int new_fz, new_fm, gcd;new_fz = fz * r.fz;new_fm = fm * r.fm;CFraction f(new_fz, new_fm);gcd = f.getGCD();new_fz /= gcd;new_fm /= gcd;CFraction ff(new_fz, new_fm);return ff;
}CFraction CFraction::div(const CFraction& r)
{int new_fz, new_fm, gcd;new_fz = fz * r.fm;new_fm = fm * r.fz;CFraction f(new_fz, new_fm);gcd = f.getGCD();new_fz /= gcd;new_fm /= gcd;CFraction ff(new_fz, new_fm);return ff;
}int CFraction::getGCD()
{int a, b, r, x;a = fm;b = fz;if (b < 0){b = -b;}if (a < b) // 确保a > b{x = a;a = b;b = x;}r = a % b;while (r != 0){a = b;b = r;r = a % b; // r为余数}return b;
}void CFraction::print()
{cout << fz << "/" << fm << endl;
}int main()
{int t, i, x1, x2, y1, y2;char ch;cin >> t;for (i = 0; i < t; i++){cin >> x1 >> ch >> x2 >> y1 >> ch >> y2;CFraction x(x1, x2);CFraction y(y1, y2);CFraction result;result = x.add(y);result.print();result = x.sub(y);result.print();result = x.mul(y);result.print();result = x.div(y);result.print();cout << endl;}return 0;
}

id:34 D.Point_Array(类+构造+对象数组)

题目描述

在这里插入图片描述
上面是我们曾经练习过的一个习题,请在原来代码的基础上作以下修改:

1、增加自写的析构函数;

2、将getDisTo方法的参数修改为getDisTo(const Point &p);

3、根据输出的内容修改相应的构造函数。

然后在主函数中根据用户输入的数目建立Point数组,求出数组内距离最大的两个点之间的距离值。

输入

测试数据的组数 t

第一组点的个数

第一个点的 x 坐标 y坐标

第二个点的 x坐标 y坐标

输出

输出每组中距离最大的两个点以及其距离(存在多个距离都是最大值的情况下,输出下标排序最前的点组合。比如如果p[0]和p[9]、p[4]和p[5]之间的距离都是最大值,那么前一个是答案,因为p[0]排序最前)

在C++中,输出指定精度的参考代码如下:

#include

#include //必须包含这个头文件

using namespace std;

void main( )

{ double a =3.141596;

cout<<fixed<<setprecision(3)<<a<<endl; //输出小数点后3位

输入样例

2
4
0 0
5 0
5 5
2 10
3
-1 -8
0 9
5 0

输出样例

Constructor.
Constructor.
Constructor.
Constructor.
The longest distance is 10.44,between p[1] and p[3].
Distructor.
Distructor.
Distructor.
Distructor.
Constructor.
Constructor.
Constructor.
The longest distance is 17.03,between p[0] and p[1].
Distructor.
Distructor.
Distructor.

题解

  • 首先分析类,Point(); // 缺省构造函数,输出,因为看到输出样例中,每输入一个点的横纵坐标都伴随着一个Constructor.的输出,故可以知道,这个缺省构造函数的作用是输出Constructor.Point(double x_value, double y_value); // 有参构造函数,给x,y赋参数的值,这个构造函数的作用是把调用这个变量的横纵坐标的值改变为参数的值;~Point(); // 析构函数,输出,同理,观察到每输入一个横纵坐标的值,都会伴随着Distructor.的输出,且这个输出在输出了距离之后才输出;double getX(); // 返回x的值,作用是当在调用这个函数时,返回横坐标的值,即是当我们需要这个变量的横坐标时,我们就可以调用这个函数;double getY();,同理;void setXY(double x1, double y1); // 赋参数的值,当调用这个函数时,这个函数就会改变横纵坐标的值为参数的值;void setX(double x_value); // 设置x的值,当在调用这个函数时,这个变量的横坐标就会变为参数的值;void setY(double y_value);,同理;double getDisTo(const Point& p); // 计算当前点到参数p的距离,在这个函数中,我们首先要定义三个变量,一个用来存储两个点横坐标之差,横坐标之差的计算是,直接用调用这个函数的横坐标的值减去参数的横坐标的值,怎么得到参数的横坐标的值呢,因为参数也是一个Point类型的变量,所以我们可以使用”."来访问它的成员,即是它的横坐标的值,另一个变量用来存储纵坐标之差,还有一个变量用来存储计算得到的两点之间的距离,并返回
  • 然后来看主函数的作用,因为我们要比较两个点的距离,而我们又会输入多个不同的点,所以我们会考虑用一个Point类型的数组来存储这些点的信息,题目有要求用动态创建的方法,所以我们采用new的方法,注意,使用后要释放内存,我们还要创建变量来存储输入进来的横纵坐标的值,这些值输入进来后我们要将他们赋值到到点的横纵坐标中,所以这时我们调用void setXY(double x1, double y1)函数
  • 然后我们编写计算两个点之间的距离的代码,我们可以使用两个嵌套的for循环,达到逐个遍历两个点,然后调用距离计算函数返回这两个点的距离,在用这个返回值与当前最大值进行比较,再进行更新和记录此时的横纵坐标的值的操作
  • 最后就是进行一些简单的输出

疑问

  • 为什么这段代码
double Point::getDisTo(const Point& p)
{double result, dx, dy;dx = x - p.x;dy = y - p.y;result = sqrt(dx * dx + dy * dy);return result;
}

不能写成

double Point::getDisTo(const Point& p)
{double result, dx, dy;dx = x - p.getX();dy = y - p.getY();result = sqrt(dx * dx + dy * dy);return result;
}

代码实现

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;class Point
{double x, y;
public:Point(); // 缺省构造函数,输出Point(double x_value, double y_value); // 有参构造函数,给x,y赋参数的值~Point(); // 析构函数,输出double getX(); // 返回x的值double getY();void setXY(double x1, double y1); // 赋参数的值void setX(double x_value); // 设置x的值void setY(double y_value);double getDisTo(const Point& p); // 计算当前点到参数p的距离
};Point::Point()
{cout << "Constructor." << endl;
}Point::Point(double x_value, double y_value)
{x = x_value;y = y_value;
}Point::~Point()
{cout << "Distructor." << endl;
}double Point::getX()
{return x;
}double Point::getY()
{return y;
}void Point::setXY(double x1, double y1) // 赋参数的值
{x = x1;y = y1;
}void Point::setX(double x_value)
{x = x_value;
}void Point::setY(double y_value)
{y = y_value;
}double Point::getDisTo(const Point& p)
{double result, dx, dy;dx = x - p.x; // 疑问dy = y - p.y;result = sqrt(dx * dx + dy * dy);return result;
}int main()
{int t, i, n, j, k, x, y;double x1, y1, max, dis;cin >> t; // 组数for (i = 0; i < t; i++){max = 0;dis = 0;cin >> n; // 点的个数Point* pp = new Point[n]; // 动态创建数组for (j = 0; j < n; j++){cin >> x1 >> y1; // 横纵坐标的值pp[j].setXY(x1, y1); // 赋参数的值}for (j = 0; j < n; j++) // 计算两个点之间的距离{for (k = j + 1; k < n; k++){dis = pp[j].getDisTo(pp[k]);if (max < dis){max = dis; // 更新x = j; // 记录横纵坐标y = k;}}}cout << "The longest distance is " << fixed << setprecision(2) << max;cout << ",between p[" << x << "]" << " and p[" << y << "]." << endl;delete[] pp; // 释放内存}return 0;
}

id:35 E.Stack(类与构造)

题目描述

class CStack
{
public:CStack(); // 建立一个10个元素的栈CStack(int s); // 建立一个具有s个元素的栈int get(int index); // 返回下标为index的栈元素void push(int n); // 进栈,top加1,把n的值存入栈顶int isEmpty(); // 判断栈否是空的,空则返回一,否则返回0int isFull(); // 判断栈是否是满的,满则返回1,否则返回0int pop(); // 出栈,返回栈顶元素,top减1~CStack(); // 析构函数,释放在构造时申请的空间
private:int* a;int size; // 栈的大小int top; // 指向栈顶
};

上面是栈类的定义,栈是一种具有先进后出特点的线性表,请根据注释,完成类中所有方法的实现,并在主函数中测试之。

堆栈类的说明如下:

  1. 堆栈的数据实际上是保存在数组a中,而a开始是一个指针,在初始化时,根据实际需求将a动态创建为数组,数组长度根据构造函数的参数决定。

  2. size实际上就是数组的长度,当使用无参构造则size为10,当使用有参构造则size为s、

  3. top表示数组下标,也表示数组中下一个存放数据的空白位置。

  4. push操作表示堆栈的数组存放一个数据,例如一开始数组为空,则top为0,当有数据要入栈时,把数据存放在a[top]的位置,然后top加1指向下一个空白位置、数据进栈只能从栈顶进。

  5. pop操作表示一个数据要出栈,数据出栈只能从栈顶出,先把top减1指向栈顶数据,然后把数据返回。

  6. 判断堆栈空的条件是top是否等于0,判断堆栈满的条件是top是否等于size

输入

测试数据的组数 t

第一个栈的大小

第一个栈的元素列表,将该列表的元素依次进栈

输出

将栈元素依次出栈

输入样例

2
5
1 2 3 4 5
7
-1 2 8 0 -3 1 3

输出样例

Constructor.
5 4 3 2 1
Destructor.
Constructor.
3 1 -3 0 8 2 -1
Destructor.

题解

  • 首先来解释类,即栈的建立,CStack(); // 建立一个10个元素的栈,在这个函数中,我们要实现将栈的大小,及数组的大小设置为10,然后我们还要动态创建一个数组,即a,还要将top,及记录指向数组的一个整形变量,就是数组的下标初始化为0,即指向第一个位置,那为什么我们要在构造函数中动态创建一个数组和初始化一个变量的值呢,因为我们这个数组已经在类中定义好了,而不是在主函数中定义好的,我们主要的操作就是对这个数组进行操作,而在主函数中我们定义一个CStack类型的变量的作用是调用这些对栈进行的操作的函数,所以最先会调用到这个构造函数,所以我们在一开始就要动态创建数组和初始化变量;CStack(int s); // 建立一个具有s个元素的栈,这也是一个构造函数,所以我们在将参数设置为栈的大小时还要动态创建数组和初始化变量,使得无论主函数调用了那个构造函数,数组都得以创建,变量得以初始化;int get(int index); // 返回下标为index的栈元素,调用这个函数时我们会得到一个值,即下表为参数的数组元素的值;void push(int n); // 进栈,top加1,把n的值存入栈顶,在这个函数中,我们把参数赋值给当前数组的空白位置,然后将数组的下标加一,使得可以存放下一次的值;int isEmpty(); // 判断栈否是空的,空则返回一,否则返回0,题目有讲怎么判断;int isFull(); // 判断栈是否是满的,满则返回1,否则返回0,同理;int pop(); // 出栈,返回栈顶元素,top减1,出栈时表示数组下标的值要减一,然后把当前数组的元素返回,要先减一再返回值,因为前面的操作会使这个这个数组下标的变量指向了一个空的地方;~CStack(); // 析构函数,释放在构造时申请的空间,释放空间和输出一句话
  • 在主函数中,我们首先要定义一个CStack类型的变量,目的是把输入进来的栈的大小设置为类中数组的大小,然后把输入进去的值通过调用进栈函数进栈,然后通过判断栈是满的还是空的,还是其他的情况,通过调用出栈函数输出元素的值,主要是使得输出和样例相同

代码实现

#include <iostream>
using namespace std;class CStack
{
public:CStack(); // 建立一个10个元素的栈CStack(int s); // 建立一个具有s个元素的栈int get(int index); // 返回下标为index的栈元素void push(int n); // 进栈,top加1,把n的值存入栈顶int isEmpty(); // 判断栈否是空的,空则返回一,否则返回0int isFull(); // 判断栈是否是满的,满则返回1,否则返回0int pop(); // 出栈,返回栈顶元素,top减1~CStack(); // 析构函数,释放在构造时申请的空间
private:int* a;int size; // 栈的大小int top; // 指向栈顶
};CStack::CStack()
{size = 10;a = new int[size]; // 分配内存空间top = 0; // 初始化cout << "Constructor." << endl;
}CStack::CStack(int s)
{size = s;a = new int[size]; // 分配内存空间top = 0; // 初始化cout << "Constructor." << endl;
}int CStack::get(int index)
{return a[index];
}void CStack::push(int n)
{a[top] = n;top++; // 指向下一个空白位置
}int CStack::isEmpty()
{if (top == 0) // 栈空{return 1;}return 0; // 不空
}int CStack::isFull()
{if (top == size) // 栈满{return 1;}return 0; // 不满
}int CStack::pop()
{top--; // 指向栈顶数据return a[top]; // 把数据返回
}CStack::~CStack()
{cout << "Destructor." << endl;delete[] a;
}int main()
{int t, i, n, j, x, result;cin >> t; // 组数for (i = 0; i < t; i++){cin >> n; // 栈的大小CStack aa(n);for (j = 0; j < n; j++){cin >> x;aa.push(x); // 进栈}for (j = 0; j < n; j++){if (aa.isFull()) // 如果栈是满的{result = aa.pop();cout << result;}else if (aa.isEmpty()) // 如果栈是空的{result = aa.pop();cout << result << endl;}else // 中间的元素{result = aa.pop();cout << " " << result;}}cout << endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nvm node.js的安装

说明&#xff1a;部分但不全面的记录 因为过程中没有截图&#xff0c;仅用于自己的学习与总结 过程中借鉴的优秀博客 可以参考 1,npm install 或者npm init vuelatest报错 2&#xff0c;了解后 发现是nvm使用的版本较低&#xff0c;于是涉及nvm卸载 重新下载最新版本的nvm 2…

激光雷达初识

一、实车激光雷达 一般在车顶位置: 二、激光雷达组成 激光收发器模块:发射激光器VCSEL+接收模块采用了SiPM(硅基光电倍增管)或者APD,一个激光器发生失效的情况,其他仍可正常工作 扫描模块:水平视场和的垂直视场的扫描,128个阵列的VCSEL激光器负责 信号处理模块:信号处…

深入理解 C++ 中的 KeyFrame 和 KeyFrame*:对象与指针的选择与管理

本文详细讨论了在 C 编程中 KeyFrame 类及其指针 KeyFrame* 的用法、区别与联系。通过探索两者的内存管理、生命周期及使用场景&#xff0c;本文旨在帮助开发者更好地理解何时以及如何选择使用对象或指针&#xff0c;从而提高代码的效率和安全性。 在 C 中&#xff0c;KeyFrame…

【电控笔记2.4】前馈技术

2.4前馈技术 前馈可以减轻控制器的负担

画板探秘系列:创意画笔第一期

前言 我目前在维护一款功能强大的开源创意画板。这个画板集成了多种创意画笔&#xff0c;可以让用户体验到全新的绘画效果。无论是在移动端还是PC端&#xff0c;都能享受到较好的交互体验和效果展示。并且此项目拥有许多强大的辅助绘画功能&#xff0c;包括但不限于前进后退、…

【SQL】DISTINCT GROUP BY

找到所有办公室里的所有角色&#xff08;包含没有雇员的&#xff09;,并做唯一输出(DISTINCT) 用DISTINCT : SELECT DISTINCT B.Building_name,E.Role FROM Buildings B LEFT JOIN Employees EON B.Building_name E.Building需要找到的结果&#xff1a;所有办公室名字&#…

iOS framework 相关知识

苹果官方目前不允许开发者使用动态库&#xff0c;所以下面只说明相关静态库使用知识&#xff0c;目前只做简单的记录&#xff0c;后续会做完整的整理 如何在同一个WorkSpace里面创建一个主工程和多个子framework 首先创键一个工程&#xff0c;然后创建一个workspace&#xf…

线程通信-java

线程通信 当多个线程操作共享多资源时&#xff0c;线程间通过某种方式相互告知自己的状态&#xff0c;以相互协调&#xff0c; 并避免无效的资源争夺。 线程通信的常见模型&#xff08;生产者与消费者模型&#xff09; 生产者线程负责生产数据 消费者线程负责消费生产者生…

表单自定义系统源码:自主创建表单 带完整的安装代码包以及搭建教程

在当今信息化社会&#xff0c;表单作为一种常见的数据收集工具&#xff0c;广泛应用于各类网站和系统中。然而&#xff0c;传统的表单系统往往功能单一&#xff0c;缺乏灵活性&#xff0c;难以满足用户多样化的需求。下面&#xff0c;小编给大家分享一款表单自定义系统源码&…

YOLOv8改进 添加大核卷积序列注意力机制LSK

一、Large Separable Kernel Attention论文 论文地址:2309.01439.pdf (arxiv.org) 二、Large Separable Kernel Attention注意力结构 LSK通过使用大型可分离卷积核来提升注意力机制的效果。在传统的注意力机制中,常用的是小型卷积核,如1x1卷积,来计算注意力权重和特征表示…

微信小程序英文版:实现一键切换中英双语版(已组件化)

已经重新优化代码做成了组件&#xff0c;需要可自取&#xff1a;https://github.com/CrystalCAI11/wechat-language-compoment 所有操作都打包在组件里不需要在额外的地方添加代码&#xff0c;直接在你需要的页面里导入组件&#xff0c;再在对应页面的onLoad()里set文本就行了。…

【嵌入式】嵌入式开发中常见的面试题(持续更新中)

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

【位运算】Leetcode 消失的两个数字

题目解析 面试题 17.19. 消失的两个数字 算法讲解 我们将这两个数组异或在一起&#xff0c;最后的结果就是a ^ b(缺失的两个数字)的结果&#xff0c;这两个缺失的数字一定是不相同的&#xff0c;所以我们就寻找他们第一个比特位是1的那个位置&#xff0c;异或的原理是&#xf…

半导体存储电路知识点总结

目录 一、SR锁存器 1.SR锁存器的概念 2.作用 二、电平触发器&#xff08;Flip-Flop&#xff09; 1.时钟信号 2.电平触发的触发器电路结构 3.带异步置位复位的电平触发器 三、边沿触发器 1.特点 2.两个D触发器组成的边沿触发D触发器 3.CMOS边沿触发D触发器的典型电路 …

FMEA分析

目录 1、FMEA的核心目的 2、FMEA的种类 3、FMEA的实施步骤 4、FMEA的SOD等级 5、FMEA的例子 FMEA&#xff08;Failure Modes and Effects Analysis&#xff0c;失效模式与影响分析&#xff09;是一种预防性的可靠性设计分析&#xff0c;用来确定潜在失效模式及其原因。它主…

【Altium Designer 20 笔记】PCB线宽与过孔尺寸

电源线&#xff1a;40mil1A&#xff08;一般翻倍给&#xff09;,地线比电源线粗一点即可&#xff1b;信号线&#xff1a;10-15mil 一、线宽 市电的火线和零线&#xff1a;80-100mil12V /24V 20mil~60mil 5V 20-30mil 3V 20-30mil GND 越宽越好20-30mil普通信号线 10mil-15mil…

比亚迪老总王传福:雨天走访县级市场,生活方式却如此简单

近期&#xff0c; 世界汽车销售排名前十的老板亲自下到一线市场调研&#xff0c;这听起来像是个奇迹&#xff0c;但这就是我们今天要说的主角——比亚迪老总王传福的故事。他不仅亲自去现场调研&#xff0c;还时常挤地铁、吃盒饭、坐经济舱&#xff0c;这和那些高高在上的企业领…

flink network buffer

Flink 的网络协议栈是组成 flink-runtime 模块的核心组件之一&#xff0c;是每个 Flink 作业的核心。它连接所有 TaskManager 的各个子任务(Subtask)&#xff0c;因此&#xff0c;对于 Flink 作业的性能包括吞吐与延迟都至关重要。与 TaskManager 和 JobManager 之间通过基于 A…

YOLOv8最新改进系列:融合DySample超轻量动态上采样算子,低延迟、高性能,目前最新上采样方法!!!遥遥领先!

YOLOv8最新改进系列&#xff1a;融合DySample超轻量动态上采样算子&#xff0c;低延迟、高性能&#xff0c;目前最新上采样方法&#xff01;&#xff01;&#xff01;遥遥领先&#xff01; DySample超轻量动态上采样算子全文戳这&#xff01;here! 详细的改进教程以及源码&am…

在EC2上面安装Skywalking9.7.0

问题 前几天在k8s集群安装了skywalking&#xff0c;说什么这种方式不行&#xff0c;客户要求单独在一台linux机器安装skywalking。现在我们来解决这个问题。 步骤 # 移动到/opt目录 cd /opt # 下载apm安装包 sudo wget https://dlcdn.apache.org/skywalking/9.7.0/apache-sk…