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.rhkb.cn/news/310225.html

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

相关文章

JAVAEE——网络初始

文章目录 网络发展史独立模式网络模式局域网LAN路由器的诞生 网络通信的基础IP地址端口号 认识协议OSI七层模型TCP/IP五层模型 网络发展史 独立模式 在原始的年代中电脑间想要通信需要两台电脑连接一根网线&#xff0c;但是一台电脑基本上只有一个接口。因此想要链接更多的电…

HCIP课后习题之一

1、路由协议用工作机制上分为那几种&#xff1f;分别是&#xff1f; A&#xff1a;两种。分别是静态路由和动态路由&#xff08;可分为IGP和EGP&#xff09; 2、IGP和EGP协议有哪些&#xff1f; A&#xff1a;IGP: RIP、OSPF、ISIS、EIGRP EGP: BGP 3、路由优先级的用途&…

自动化测试selenium(2)

目录 WebDriver介绍 WebDriver使用 使用WebDriver驱动操作浏览器(打开一个百度) WebDriver 相关API 定位元素 操作元素 上一篇主要介绍了自动化测试的概念以及selenium的基本原理, 这里我们来讲一下如何利用selenium来写测试用的脚本. WebDriver介绍 Selenium是一个用于…

1043: 利用栈完成后缀表达式的计算

解法&#xff1a; #include<iostream> #include<stack> using namespace std; int main() {char a;stack<int> sk;while (cin >> a && a ! #) {if (a > 0 && a < 9) {sk.push(a - 0);}else {int num2 sk.top();sk.pop();int n…

javaWeb项目-外面点餐系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、Spring Boot框架 …

书生·浦语大模型全链路开源体系-第3课

书生浦语大模型全链路开源体系-第3课 书生浦语大模型全链路开源体系-第3课相关资源RAG 概述在 InternLM Studio 上部署茴香豆技术助手环境配置配置基础环境下载基础文件下载安装茴香豆 使用茴香豆搭建 RAG 助手修改配置文件 创建知识库运行茴香豆知识助手 在茴香豆 Web 版中创建…

逆向IDA中Dword,数据提取

我们可以看见数据是这样的&#xff0c;第一个是1cc 但是我们shifte就是 这个因为他的数据太大了&#xff0c;导致高位跑后面去了 这个时候&#xff0c;我们右键——convert——dword 这样就可以提取到争取的数据了 比如第一个数据 0x1cc a0xcc b0x1 print(hex((b<<8…

【Java】maven的生命周期和概念图

maven的生命周期&#xff1a; 在maven中存在三套"生命周期"&#xff0c;每一套生命周期,相互独立,互不影响的,但是中同一套生命周期里,执行后面的命令会自动先执行前面的命令 CleanLifeCycle&#xff1a;清理的生命周期 clean defaultLifeCycle&#xff1a;默认的…

“成像光谱遥感技术中的AI革命:ChatGPT在遥感领域中的应用“

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用&#xff0c;人工智能…

智能物联网远传冷水表管理系统

智能物联网远传冷水表管理系统是一种基于物联网技术的先进系统&#xff0c;旨在实现对冷水表的远程监测、数据传输和智能化管理。本文将从系统特点、构成以及带来的效益三个方面展开介绍。 系统特点 1.远程监测&#xff1a;系统可以实现对冷水表数据的远程监测&#xff0c;无…

C语言洛谷题目分享(9)奇怪的电梯

目录 1.前言 2.题目&#xff1a;奇怪的电梯 1.题目描述 2.输入格式 3.输出格式 4.输入输出样例 5.说明 6.题解 3.小结 1.前言 哈喽大家好啊&#xff0c;前一段时间小编去备战蓝桥杯所以博客的更新就暂停了几天&#xff0c;今天继续为大家带来题解分享&#xff0c;希望大…

MongoDB副本集部署(windows)

环境准备 本教程演示mongodb4.4 副本集部署&#xff08;一主两从&#xff0c;伪分布式&#xff09; 节点配置主节点localhost:27017从节点1localhost:27018从节点2localhost:27019 每一个节点&#xff08;实例&#xff09;都创建对应的数据文件&#xff08;data&#xff09;…

【JavaWeb】Day45.Mybatis——入门程序

什么是MyBatis? MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发。 &#xff08;持久层&#xff1a;指的是就是数据访问层(dao)&#xff0c;是用来操作数据库的。&#xff09; &#xff08;框架&#xff1a;是一个半成品软件&#xff0c;是一套可重用的、通用…

Redis实现延迟任务的几种方案

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1.前言 2.Redis如何实现延迟任务&#xff1f; 3.代码实现 3.1. 过期键通知事…

论文速读:Do Generated Data Always Help Contrastive Learning?

在对比学习领域&#xff0c;最近很多研究利用高质量生成模型来提升对比学习 给定一个未标记的数据集&#xff0c;在其上训练一个生成模型来生成大量的合成样本&#xff0c;然后在真实数据和生成数据的组合上执行对比学习这种使用生成数据的最简单方式被称为“数据膨胀”这与数据…

#新版Onenet云平台使用(ESP8266 AT指令上报数据以及公网MQTT服务器连接测试)

1.上云方式&#xff1a;MQTT 参考&#xff1a; 新版ONENET物联网开放平台ATMQTT指令连接_at指令连接onenet的mqtt-CSDN博客https://blog.csdn.net/lilbye/article/details/131770196 ESP8266-01s入门&#xff1a;AT指令讲解、上云与MQTT通信教程-物联沃-IOTWORD物联网https:…

hadoop最新详细版安装教程 2024 最新版

文章目录 hadoop安装教程 2024最新版提前准备工作用户配置安装 SSH Server免密登录设置编辑 SSH server 配置文件配置Java环境查看java 版本验证 环境变量设置安装Hadoop下载hadoop解压hadoop查看hadoop 版本hadoop 配置编辑编辑配置文件core-site.xml编辑配置文件hdfs-site.xm…

系统边界图

系统边界图的定义&#xff1a; 系统边界图是系统工程和软件工程中的一种图形化工具&#xff0c;用于描述系统与外部世界之间的交互和界限。它展示了系统的组成部分以及这些组件如何与外部实体进行通信和交互。系统边界图通常包括系统内部的各个组件、外部实体以及它们之间的通信…

企业怎么建立自己的防泄密系统?

企业怎么建立自己的防泄密系统&#xff1f; 数据防泄密防泄密的关键是人&#xff0c;评估一家企业的数据安全现状&#xff0c;必须以人为本。企业领导是否有数据保密意识&#xff1f;员工是否能遵守保密制度&#xff1f;这都是关键。企业领导和员工具备良好的保密意识&#xf…

javaee初阶———多线程(三)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程专题第三篇,关于线程安全方面的内容 如果有不足的或者错误的请您指出! 目录 八、线程安全问题(重点)1.一个典型的线程不安全的例子2.出现线程不安全的原因3.解决线程不安…