设计一个多边形类
设计多边形类 Polygon(由 n 个 Point 类组成),要求如下:
(1) Polygon 类包括私有成员:nLength,表示多边形中顶点数;
(2) Polygon 类包括私有成员 Vertex,用以存放 nLength 个顶点的坐标;
(3) 通过 Set(int idx, Point pnt) 函数,为第 idx 个顶点赋值;
(4) 设计公有成员函数 Perimeter,计算多边形的周长。
Point 类的定义如下:
class Point
{
public:
float x, y;
};
它在main函数中使用情况如下:
int main()
{
int n = 0;
Point pnt;
cin >> n;
Polygon po(n);
for (int i = 0; i < n; i++)
{
cin >> pnt.x >> pnt.y;
po.Set(i, pnt);
}
printf("%4.1f", po.Perimeter());
return 1;
}
【输入形式】
第1行输入多边形的顶点数量(大于2)
第2~n+1行输入多边形点的坐标(要求各顶点不能相同)
【输出形式】输出多边形的周长
【样例输入】
3
1 2
1 4
3 4
【样例输出】
6.8
【样例说明】输入时数据之间用单个空格隔开,输出为实数类型,保留一位小数。
【提示说明】两点间距离 sqrt ( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) )
#include <iostream> // 引入输入输出流库
#include <cmath> // 引入数学库,用于计算平方根和幂运算
using namespace std;
// 定义Point类,表示二维空间中的一个点
class Point
{
public:
float x, y; // 点的x和y坐标
};
// 定义Polygon类,表示一个多边形
class Polygon
{
private:
int nLength; // 多边形的顶点数量
Point *Vertex; // 指向一个Point类型的指针,用于存储多边形的顶点
// 定义一个私有成员函数,用于计算两点之间的距离
float distance(Point a, Point b)
{
return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}
public:
// Polygon的构造函数,接收一个整数n作为参数,表示多边形的顶点数量
Polygon(int n) : nLength(n)
{
Vertex = new Point[n]; // 动态分配n个Point对象的空间
}
// Polygon的析构函数,用于释放之前动态分配的内存
~Polygon()
{
delete[] Vertex; // 删除Point数组
}
// 定义一个成员函数,用于设置多边形的顶点
void Set(int idx, Point pnt)
{
if (idx >= 0 && idx < nLength) // 检查索引是否在有效范围内
{
Vertex[idx] = pnt; // 将传入的点赋值给对应的顶点
}
}
// 定义一个成员函数,用于计算多边形的周长
float Perimeter()
{
float perimeter = 0.0f; // 初始化周长为0
for (int i = 0; i < nLength; i++) // 遍历每一个顶点
{
int next = (i + 1) % nLength; // 计算下一个顶点的索引,如果i是最后一个顶点,则next为0
perimeter += distance(Vertex[i], Vertex[next]); // 计算当前顶点到下一个顶点的距离,并累加到周长中
}
return perimeter; // 返回周长
}
};
int main()
{
int n = 0;
cin >> n; // 从标准输入读取多边形的顶点数量
if (n <= 2) // 如果顶点数量小于等于2,则不是多边形
{
cerr << "多边形顶点数量必须大于2" << endl; // 输出错误信息
return 1; // 返回错误码1
}
Polygon po(n); // 创建一个具有n个顶点的多边形对象
Point pnt;
for (int i = 0; i < n; i++) // 遍历每一个顶点
{
cin >> pnt.x >> pnt.y; // 从标准输入读取顶点的x和y坐标
po.Set(i, pnt); // 将顶点设置到多边形对象中
}
printf("%4.1f\n", po.Perimeter()); // 计算并输出多边形的周长,保留一位小数
return 0; // 程序正常结束,返回0
}
设计建筑物类
【问题描述】设计一个建筑物类 Building,由它派生出教学楼类 Teach-Building 和宿舍楼类 Dorm-Building,前者包括教学楼编号、层数、教室数、总面积等基本信息,后者包括宿舍楼编号、层数、宿舍数、总面积和容纳学生总人数等基本信息。根据教学楼和宿舍楼属性设计出 Building 类,在类中完成输出每种建筑物的属性。编写无参数的构造函数初始化两种楼信息。
【输入形式】首先输入教学楼信息,再输入宿舍楼信息,信息之间用单个空格分隔
【输出形式】先输出宿舍楼信息,再输出教学楼信息
【样例输入】
mainteachbuild 56 6 66 18000
北苑男生宿舍",41,5,75,3750,300
southmaledormitory 41 5 75 3750 300
【样例输出】
southmaledormitory 41 5 75 3750 300
mainteachbuild 56 6 66 18000
#include <iostream>
#include <string>
class Building
{
protected:
std::string name; // 建筑物的名称
std::string id; // 建筑物的编号
int floors; // 层数
float area; // 面积
public:
Building() : name(""), id(""), floors(0), area(0.0f) {}
virtual ~Building() {}
virtual void printInfo() const = 0; // 纯虚函数,强制派生类实现
};
class TeachBuilding : public Building
{
private:
int classrooms; // 教室数
public:
TeachBuilding() : Building(), classrooms(0) {}
void setInfo(const std::string &name, const std::string &id, int floors, int classrooms, float area)
{
this->name = name;
this->id = id;
this->floors = floors;
this->classrooms = classrooms;
this->area = area;
}
void printInfo() const override
{
std::cout << name << " " << id << " " << floors
<< " " << classrooms << " " << area << std::endl;
}
};
class DormBuilding : public Building
{
private:
int dorms; // 宿舍数
int capacity; // 容纳学生总人数
public:
DormBuilding() : Building(), dorms(0), capacity(0) {}
void setInfo(const std::string &name, const std::string &id, int floors, int dorms, float area, int capacity)
{
this->name = name;
this->id = id;
this->floors = floors;
this->dorms = dorms;
this->area = area;
this->capacity = capacity;
}
void printInfo() const override
{
std::cout << name << " " << id << " " << floors
<< " " << dorms << " " << area
<< " " << capacity << std::endl;
}
};
int main()
{
std::string teachName, dormName;
std::string teachId, dormId;
int teachFloors, dormFloors;
int teachClassrooms, dormDorms, dormCapacity;
float teachArea, dormArea;
// 输入教学楼信息
std::cin >> teachName >> teachId >> teachFloors >> teachClassrooms >> teachArea;
TeachBuilding teachBuilding;
teachBuilding.setInfo(teachName, teachId, teachFloors, teachClassrooms, teachArea);
// 输入宿舍楼信息
std::cin >> dormName >> dormId >> dormFloors >> dormDorms >> dormArea >> dormCapacity;
DormBuilding dormBuilding;
dormBuilding.setInfo(dormName, dormId, dormFloors, dormDorms, dormArea, dormCapacity);
// 输出建筑物信息
dormBuilding.printInfo();
teachBuilding.printInfo();
return 0;
}
设计实现教师类和教授类
【问题描述】
-
实现 Birthday 类。包含私有变量 year,month,day 三个数据成员。
-
实现 Teacher 教师类。
2.1 包含私有变量 姓名 name,基本工资 salary 数据成员。
2.2 实现无参的构造函数对 name 和 salary 进行初始化,默认分别为 wumingshi 和 5000。
2.3 实现带 2 个参数的构造函数对 name 和 salary 进行初始化。
2.4 实现获取基本工资的 getSalary 成员函数,得到对象的 salary 值。
2.5 实现显示 show 函数,输出 name 和 salary,中间用空格隔开 -
通过继承 Teacher 类的方式,实现 Professor 教授类。
3.1 包含私有的类成员变量 birth(是 Birthday 类对象,代表出生日期),私有变量 *revenue(动态数组,代表收入),私有变量 typeNum(代表收入种类的数量,即 revenue 长度)。
3.2 实现构造函数分别对基类和派生类成员进行初始化,即对 name, salary, birth, *revenue, typeNum 进行初始化。
3.3 实现拷贝构造函数(深拷贝)。
3.4 实现计算教授的工资总和成员函数 getTotal,计算方法为 工资总和 = 做为教师的基本工资Salary + revenue中的各类收入总和。 -
按以上要求实现 Birthday、Teacher 和 Professor 类,使得以下函数代码可以直接用,并输出相应的结果
int main(){
char name[20];
int salary;
Teacher t1;
cin>>name>>salary;
Teacher t2(name,salary);
int year, month, day, num,*revenue;
cin>>name>>salary>>year>>month>>day>>num;
Birthday b(year, month, day);
revenue=new int[num];
for(int i=0;i<num;i++){
cin>>revenue[i];
}
Professor p1(name,salary,b,revenue,num);
t1.show();
t2.show();
p1.show();
cout<<p1.getTotal();
return 0;
}
【输入形式】
【第一行】教师类姓名和收入
【第二行】教授类姓名、收入、出生日期和其它收入数量 n
【n 行】其它收入,每行代表一个收入
【输出形式】
读懂前面的程序,按照以下顺序各占一行输出:
t1.show();
t2.show();
p1.show();
cout << p1.getTotal();
【样例输入】
xiaoming 6000
zhangshan 7000 1992 2 2 3
100
200
300
【样例输出】
wumingshi 5000
xiaoming 6000
zhangshan 7000
7600
#include <iostream>
#include <cstring>
using namespace std;
// Birthday 类
class Birthday
{
private:
int year;
int month;
int day;
public:
Birthday(int y = 1900, int m = 1, int d = 1) : year(y), month(m), day(d) {}
};
// Teacher 类
class Teacher
{
private:
char name[20];
int salary;
public:
// 无参构造函数
Teacher()
{
strcpy(name, "wumingshi");
salary = 5000;
}
// 带两个参数的构造函数
Teacher(const char *n, int s)
{
strcpy(name, n);
salary = s;
}
// 获取基本工资
int getSalary() const { return salary; }
// 显示
void show() const
{
cout << name << " " << salary << endl;
}
};
// Professor 类
class Professor : public Teacher
{
private:
Birthday birth;
int *revenue;
int typeNum;
public:
// 构造函数
Professor(const char *n, int s, const Birthday &b, int *r, int num)
: Teacher(n, s), birth(b), typeNum(num)
{
revenue = new int[typeNum];
for (int i = 0; i < typeNum; i++)
{
revenue[i] = r[i];
}
}
// 拷贝构造函数
Professor(const Professor &other)
: Teacher(other), birth(other.birth), typeNum(other.typeNum)
{
revenue = new int[typeNum];
for (int i = 0; i < typeNum; i++)
{
revenue[i] = other.revenue[i];
}
}
// 析构函数
~Professor()
{
delete[] revenue;
}
// 计算工资总和
int getTotal() const
{
int total = Teacher::getSalary();
for (int i = 0; i < typeNum; i++)
{
total += revenue[i];
}
return total;
}
};
// 主函数
int main()
{
char name[20];
int salary;
Teacher t1;
cin >> name >> salary;
Teacher t2(name, salary);
int year, month, day, num, *revenue;
cin >> name >> salary >> year >> month >> day >> num;
Birthday b(year, month, day);
revenue = new int[num];
for (int i = 0; i < num; i++)
{
cin >> revenue[i];
}
Professor p1(name, salary, b, revenue, num);
t1.show();
t2.show();
p1.show();
cout << p1.getTotal();
return 0;
}
设计一个点类和一个线段类
【问题描述】
设计二维点类 Point,包括私有成员:横坐标 x,纵坐标 y。能够实现以下操作:
(1) 无参构造函数,初始化 x=0,y=0;
(2) 有参构造函数 Point(int x, int y),初始化 x,y;
(3) 提供公有接口 SetX,SetY,为 x,y 赋值;
(4) 提供公有接口 GetX,GetY,访问私有成员 x,y;
(5) 打印函数 print,打印点对象坐标。
设计一个类 Line 描述,使 Line 类中包括 Point 类的两个对象,Line 可以计算线段长度的功能,要求如下:
(1) 通过构造函数 Line 为线段的两个点进行初始化;
(2) 设置一个点的坐标值;
(3) 计算出这两点间的距离;
(4) 输出线段的距离。
要求输入两个点的坐标,第一个点的坐标通过构造函数完成,第二个点的坐标通过设置函数完成,最后输出这两点的距离。
【输入形式】分别输入两点的坐标,先输入x,再输入y,坐标值为整型数。
【输出形式】输出两点间的距离
【样例输入】2 3 4 5
【样例输出】2.8
【样例说明】输入时数据之间用单个空格隔开,输出为实数类型,保留一位小数。
【评分标准】两点间距离 sqrt ( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) )
#include <iostream>
#include <cmath>
#include <iomanip> // 用于设置输出格式
// 定义Point类
class Point
{
private:
int x;
int y;
public:
// 无参构造函数
Point() : x(0), y(0) {}
// 有参构造函数
Point(int x, int y) : x(x), y(y) {}
// 设置x坐标
void SetX(int x)
{
this->x = x;
}
// 设置y坐标
void SetY(int y)
{
this->y = y;
}
// 获取x坐标
int GetX() const
{
return x;
}
// 获取y坐标
int GetY() const
{
return y;
}
// 打印坐标
void print() const
{
std::cout << "(" << x << ", " << y << ")" << std::endl;
}
};
// 定义Line类
class Line
{
private:
Point startPoint;
Point endPoint;
public:
// 构造函数,初始化起点
Line(int x1, int y1) : startPoint(x1, y1) {}
// 设置终点坐标
void setEndPoint(int x2, int y2)
{
endPoint = Point(x2, y2);
}
// 计算线段长度
double calculateLength() const
{
int dx = endPoint.GetX() - startPoint.GetX();
int dy = endPoint.GetY() - startPoint.GetY();
return std::sqrt(dx * dx + dy * dy);
}
// 输出线段长度
void printLength() const
{
std::cout << std::fixed << std::setprecision(1) << calculateLength() << std::endl;
}
};
int main()
{
// 读取第一个点的坐标
int x1, y1;
std::cin >> x1 >> y1;
// 创建Line对象,初始化起点
Line line(x1, y1);
// 读取第二个点的坐标
int x2, y2;
std::cin >> x2 >> y2;
// 设置终点
line.setEndPoint(x2, y2);
// 输出线段长度
line.printLength();
return 0;
}
编写学生和教师类
【问题描述】编写一个学生和教师数据输入和显示程序,学生数据有编号、姓名、班号和成绩,教师数据有编号、姓名、职称和部门。要求将编号、姓名输入和显示设计成一个 person 类,并作为学生数据操作类 student 和教师数据操作类 teacher 的基类。
【输入形式】分别输入一个学生信息和一个教师信息,用数据 1 或者 0 来进行区分,1 表示输入的学生信息,0 表示输入的是教师信息,学生信息有编号,姓名、班级和成绩,教师信息有编号、姓名、职称和部门。
【输出形式】输出是先输出学生基本信息,编号、姓名和班级,再输出教师的基本信息,编号、姓名和部门
【样例输入】
1 2001 wangfang 102 98
0 123456 zhanghao jiangshi compute
【样例输出】
2001 wangfang 102
123456 zhanghao compute
【样例说明】学生成绩按整数类型处理,输入输出是用单个空格把数据隔开,输出学生信息另起一行再输出教师信息。
#include <iostream>
#include <string>
// 基类 Person
class Person
{
protected:
int id;
std::string name;
public:
Person(int id, const std::string &name) : id(id), name(name) {}
virtual void display() const = 0; // 纯虚函数,确保子类必须实现
virtual ~Person() {}
};
// 学生类 Student 继承自 Person
class Student : public Person
{
private:
std::string className;
int score; // 注意:虽然输入中有成绩,但输出要求中并未提及,因此这里不打印成绩
public:
Student(int id, const std::string &name, const std::string &className, int score)
: Person(id, name), className(className), score(score) {}
// 显示学生信息:编号、姓名、班级
void display() const override
{
std::cout << id << " " << name << " " << className << std::endl;
}
};
// 教师类 Teacher 继承自 Person
class Teacher : public Person
{
private:
std::string title; // 注意:虽然输入中有职称,但输出要求中并未提及,因此这里不打印职称
std::string department;
public:
Teacher(int id, const std::string &name, const std::string &title, const std::string &department)
: Person(id, name), title(title), department(department) {}
// 显示教师信息:编号、姓名、部门
void display() const override
{
std::cout << id << " " << name << " " << department << std::endl;
}
};
int main()
{
int type;
Student *student = nullptr; // 将学生对象的指针初始化为 nullptr
Teacher *teacher = nullptr; // 将教师对象的指针初始化为 nullptr
int n = 0;
while (n != 2)
{
std::cin >> type;
if (type == 1)
{
// 学生信息
int id, score;
std::string name, className;
std::cin >> id >> name >> className >> score;
student = new Student(id, name, className, score); // 使用 new 来初始化学生对象
}
else if (type == 0)
{
// 教师信息
int id;
std::string name, title, department;
std::cin >> id >> name >> title >> department;
teacher = new Teacher(id, name, title, department); // 使用 new 来初始化教师对象
}
else
{
std::cerr << "格式错误!" << std::endl;
}
n++;
}
// 检查对象是否已经被初始化,然后调用 display 方法
if (student != nullptr)
{
student->display();
delete student; // 释放学生对象的内存
}
if (teacher != nullptr)
{
teacher->display();
delete teacher; // 释放教师对象的内存
}
return 0;
}
统计班级成绩排序
【问题描述】编写一个班级成绩排序程序。班级有班级号,班级人数和若干学生,每个学生有学号、姓名、三门课成绩。按学生总成绩从高到底进行排序。
【输入形式】输入班级号,及班级人数;然后输入班级中每个学生信息。
【输出形式】输出班级信息,以及按总成绩从高到底输出学生信息。
【样例输入】1(班级号) 3(班级人数)
1 a 98 89 78(输入三个学生信息,学号、姓名、三门课成绩)
2 b 78 86 67
3 c 87 98 96
【样例输出】class no:1 numbers:3
3 c 87 98 96 281
1 a 98 89 78 265
2 b 78 86 67 231
【提示】编写两个类:学生类和班级类!
#include <iostream>
#include <vector>
#include <algorithm>
// 学生类
class Student
{
public:
int id;
std::string name;
std::vector<int> scores;
Student(int id, const std::string &name, int score1, int score2, int score3)
: id(id), name(name), scores{score1, score2, score3} {}
// 计算总成绩
int getTotalScore() const
{
int total = 0;
for (int score : scores)
{
total += score;
}
return total;
}
// 打印学生信息
void print() const
{
std::cout << id << " " << name << " ";
for (int score : scores)
{
std::cout << score << " ";
}
std::cout << getTotalScore() << std::endl;
}
};
// 班级类
class Classroom
{
public:
int classNo;
std::vector<Student> students;
Classroom(int classNo) : classNo(classNo) {}
// 添加学生
void addStudent(const Student &student)
{
students.push_back(student);
}
// 根据学生总成绩排序
void sortByTotalScore()
{
std::sort(students.begin(), students.end(), [](const Student &a, const Student &b)
{ return a.getTotalScore() > b.getTotalScore(); });
}
// 打印班级信息和学生信息
void print() const
{
std::cout << "class no:" << classNo << " numbers:" << students.size() << std::endl;
for (const Student &student : students)
{
student.print();
}
}
};
// 比较函数,用于std::sort的自定义排序
bool compareByTotalScore(const Student &a, const Student &b)
{
return a.getTotalScore() > b.getTotalScore();
}
int main()
{
int classNo, numStudents;
std::cin >> classNo >> numStudents;
Classroom classroom(classNo);
for (int i = 0; i < numStudents; ++i)
{
int id, score1, score2, score3;
std::string name;
std::cin >> id >> name >> score1 >> score2 >> score3;
Student student(id, name, score1, score2, score3);
classroom.addStudent(student);
}
classroom.sortByTotalScore();
classroom.print();
return 0;
}
私有继承编程练习题(片段)
【问题描述】
编写程序,有一个基类交通工具类和派生类汽车类,基类中有数据成员车轮个数wheels和车重weight;汽车类是它的私有派生类,有数据成员核载人数。编写两个类的构造函数和输出函数按照指定格式输出相关数据。
【输入形式】依次输入车轮数和车重以及核载人数,空格分隔,回车结束。
【输出形式】分别输出车轮数和车重以及核载人数,每行显示一个数据。
【样例输入】
6 80.0 2
【样例输出】
wheels:6
weight:80
passenger load:2
【样例输入】
6 80.12 2
【样例输出】
wheels:6
weight:80.12
passenger load:2
#include <iostream>
#include <cmath>
using namespace std;
class Vehicle
{
private:
int wheels; // 车轮数
double weight; // 车身重量
public:
// 编写构造函数
Vehicle(int wh, double wt) : wheels(wh), weight(wt) {}
// 编写输出函数
void display() const
{
cout << "wheels:" << wheels << endl;
cout << "weight:" << weight << endl;
}
};
class Cars : private Vehicle
{
private:
int passengerLoad; // 核载人数
public:
// 编写构造函数
Cars(int wh, double wt, int pl) : Vehicle(wh, wt), passengerLoad(pl) {}
// 编写输出函数
void display() const
{
Vehicle::display(); // 调用基类的输出函数
cout << "passenger load:" << passengerLoad << endl;
}
};
int main()
{
int wh, carr;
double wei;
cin >> wh >> wei >> carr;
Cars car(wh, wei, carr); // 创建Cars对象
car.display(); // 调用Cars的输出函数
return 0;
}
利用类的继承实现点和圆的位置关系判定(片段)
【问题描述】
编写程序,有一个基类点类和派生类圆类,基类中有数据成员平面坐标x和y;派生类有数据成员圆半径。编写两个类的构造函数和针对本类数据成员的读、写函数。输入圆半径以及圆心坐标,输入n个坐标点,判断这n个坐标是在圆内还是圆外并输出相关信息(圆上的点不输出)。
【输入形式】输入圆半径以及圆心坐标,输入正整数n及n个坐标点。
【输出形式】输出n个坐标点中在圆内和圆外的坐标点信息。
【样例输入】
10 0 0
4 10 0 0 -10 6 -5 -12 -20
【样例输出】
(6,-5) in the circle
(-12,-20) out of the circle
【评分标准】两点间距离公式:sqrt ( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) )
#include <iostream> // 包含标准输入输出库
#include <cmath> // 包含数学运算函数,如sqrt()和pow()
using namespace std; // 使用标准命名空间
// 定义Point类,表示二维平面上的一个点
class Point
{
private:
double x; // 点的x坐标
double y; // 点的y坐标
public:
// 默认构造函数,不执行任何操作
Point() {}
// 带参数的构造函数,用于初始化点的坐标
Point(double a, double b) : x(a), y(b) {};
// 设置x坐标的方法
void setX(double a)
{
x = a;
}
// 设置y坐标的方法
void setY(double b)
{
y = b;
}
// 获取x坐标的方法
double GetX() const
{
return x;
}
// 获取y坐标的方法
double GetY() const
{
return y;
}
};
// 定义Circle类,表示二维平面上的一个圆,继承自Point类
class Circle : public Point
{
private:
double radius; // 圆的半径
public:
// 构造函数,初始化圆的圆心和半径
Circle(double a, double b, double c) : Point(b, c) { radius = a; }
// 判断一个点是否在圆内的方法
void inCircle(const Point &p)
{
// 计算点与圆心之间的距离
double distance = sqrt(pow(GetX() - p.GetX(), 2) + pow(GetY() - p.GetY(), 2));
// 判断点与圆心的距离与半径的关系
if (distance < radius)
cout << "(" << p.GetX() << "," << p.GetY() << ")" << " in the circle" << endl;
else if (distance > radius) // 添加了else if条件,确保点不在圆内时输出正确的信息
cout << "(" << p.GetX() << "," << p.GetY() << ")" << " out of the circle" << endl;
// 注意:原代码中缺少对点正好在圆上的情况的处理,这里也没有添加
}
};
int main()
{
double r, x, y;
// 输入圆的半径和圆心坐标
cin >> r >> x >> y;
// 创建Circle对象,并初始化其半径和圆心坐标
Circle cl(r, x, y);
int n, i;
cin >> n; // 输入要判断的点的数量
for (i = 0; i < n; i++)
{
cin >> x >> y; // 输入点的坐标
Point p(x, y); // 创建Point对象,并初始化其坐标
// 调用Circle对象的inCircle方法,判断点是否在圆内或圆外
cl.inCircle(p);
}
return 0;
}
今天的内容就分享这么多
求三连!!!
求关注!!!