多态与泛型计分作业
选择排序函数模板SortArray
【问题描述】采用模板技术定义选择排序函数模板SortArray
【输入形式】一系列数字
【输出形式】排序后的数字
【样例输入】3 2 1 4 5 6 7 8 9 10
【样例输出】1 2 3 4 5 6 7 8 9 10
#include <iostream>
using namespace std;
const int MAX_SIZE = 10;
// 函数模板SortArray,用于选择排序
template <typename T>
void SortArray(T arr[], int size)
{
for (int i = 0; i < size - 1; i++)
{
int minIndex = i;
for (int j = i + 1; j < size; j++)
{
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
}
if (minIndex != i)
{
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
int main()
{
int ar[MAX_SIZE];
for (int i = 0; i < MAX_SIZE; i++)
cin >> ar[i];
SortArray<int>(ar, MAX_SIZE);
cout << ar[0];
for (int i = 1; i < MAX_SIZE; i++)
cout << " " << ar[i];
cout << endl;
return 0;
}
堆栈类模板程序
【问题描述】将堆栈设计成一个类模板,在堆栈中可以存放任意类型的数据。要求成员函数至少包含构造函数,析构函数,出栈函数pop,入栈函数push(),堆栈为空判断函数IsEmpty()和堆栈为满判断函数IsFull();成员数据至少包括一个指针变量用以保存堆栈数据。
【输入形式】输入一组字符数据和一组整型数据用以验证堆栈功能。
【输出形式】按照样例输出格式进行输出。
【样例输入】
w95oI
43 30 90 15 21 43 99 3 55 9
【样例输出】
int stack full!
int stack full!
I o 5 9 w
3 99 43 21 15 90 30 43
#include <iostream>
using namespace std;
template <typename T>
class Stack
{
private:
T *space;
int maxSize;
int top;
public:
Stack(int size)
{
maxSize = size;
top = -1;
space = new T[maxSize];
}
~Stack()
{
delete[] space;
}
bool push(T data)
{
if (IsFull())
{
return false;
}
space[++top] = data;
return true;
}
T pop()
{
if (IsEmpty())
{
// 这里可以抛出一个异常
throw "Stack is empty!";
}
return space[top--];
}
bool IsEmpty()
{
return top == -1;
}
bool IsFull()
{
return top == maxSize - 1;
}
};
int main()
{
char ch;
Stack<char> s1(5);
Stack<int> s2(8);
int i, n;
for (i = 0; i < 5; i++)
{
cin >> ch;
s1.push(ch);
}
for (i = 0; i < 10; i++)
{
cin >> n;
if (!s2.push(n))
cout << "int stack full!" << endl;
}
while (!s1.IsEmpty())
cout << s1.pop() << ' ';
cout << endl;
while (!s2.IsEmpty())
cout << s2.pop() << ' ';
cout << endl;
return 0;
}
顺序表模板类
【问题描述】根据声明的顺序表的模板类,编程实现指定功能,具体功能见代码注释部分。
【输入形式】输入字符数据和整型数据验证模板类
【输出形式】输出插入删除操作后的最终的顺序表
【样例输入】
a b c d
2 x
1
1 2 3 4
1 100
2
【样例输出】
a x c d
4 100 2 1
#include <iostream>
using namespace std;
// 声明顺序表模板类
template <typename Type>
class SqList
{
public:
SqList(int n); // 构造函数,开辟n个顺序表空间
~SqList(); // 析构函数,释放开辟的空间
bool isEmpty(); // 空表判断
void displayList(); // 依次输出顺序表元素,空格分隔
void insert(int index, Type elem); // 在指定的索引的位置插入元素
void deleteList(int index); // 删除指定索引位置的元素
private:
Type *pelem;
int length; // 表中实际存储的数据元素的数量
};
// 实现顺序表模板类成员函数
template <typename Type>
SqList<Type>::SqList(int n)
{
pelem = new Type[n];
length = 0;
}
template <typename Type>
SqList<Type>::~SqList()
{
delete[] pelem;
}
template <typename Type>
bool SqList<Type>::isEmpty()
{
return length == 0;
}
template <typename Type>
void SqList<Type>::displayList()
{
for (int i = 0; i < length; i++)
{
cout << pelem[i] << ' ';
}
cout << endl;
}
template <typename Type>
void SqList<Type>::insert(int index, Type elem)
{
if (index < 0 || index > length)
{
cout << "Insert failed! Index out of range." << endl;
return;
}
// 注意:这里没有检查是否已满,因为数组大小在构造函数中已固定
for (int i = length; i > index; i--)
{
pelem[i] = pelem[i - 1];
}
pelem[index] = elem;
length++;
}
template <typename Type>
void SqList<Type>::deleteList(int index)
{
if (index < 0 || index >= length)
{
cout << "Delete failed! Index out of range." << endl;
return;
}
for (int i = index; i < length - 1; i++)
{
pelem[i] = pelem[i + 1];
}
length--;
}
int main()
{
int i, n, index;
char ch;
SqList<char> sc(10);
for (i = 0; i < 4; i++)
{ // 添加4个字符到顺序表
cin >> ch;
sc.insert(i, ch);
}
cin >> index >> ch; // 读取插入位置和插入的字符
sc.insert(index, ch);
cin >> index; // 读取删除的位置
sc.deleteList(index);
SqList<int> si(5);
for (i = 0; i < 4; i++)
{ // 添加4个整数到顺序表
cin >> n;
si.insert(0, n); // 注意:这里总是插入到表头,如果要根据index插入需要修改逻辑
}
cin >> index >> n; // 读取插入位置和插入的整数
si.insert(index, n);
cin >> index; // 读取删除的位置
si.deleteList(index);
sc.displayList();
si.displayList();
return 0;
}
图形类、点类、和圆类编程
【问题描述】已知图形类Shape是一个表示图形的抽象类,Area( )为求图形面积的函数,Perimeter( )为求图形周长的函数,Print()为 输出图形的基本信息。分别设计图形类(Shape)、点类(Point)和圆类(Circle),要求根据如下已知代码,实现相关类。
【输入形式】按序输入三个整型数,分别为圆心横坐标、圆心纵坐标、和半径
【输出形式】按样例输出格式输出相关数据
【样例输入】2 4 5
【样例输出】
x=2,y=4
Area=0
Perimeter=0
x=2,y=4,r=5
Area=78.5398
Perimeter=31.4159
【样例说明】输出时行与行之间无空行,小数点输出多少位编程时不需要理会。
#include <iostream>
using namespace std;
const double PI = 3.1415926;
// 在此补全图形类(Shape)、点类(Point)和圆类(Circle)的相关代码
class Shape
{
public:
virtual double Area() const = 0;
virtual double Perimeter() const = 0;
virtual void Print() const = 0;
};
class Point : public Shape
{
private:
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
double Area() const override { return 0; }
double Perimeter() const override { return 0; }
void Print() const override
{
cout << "x=" << x << ",y=" << y;
}
};
class Circle : public Shape
{
private:
Point center;
double radius;
public:
Circle(int x, int y, double r) : center(x, y), radius(r) {}
double Area() const override
{
return PI * radius * radius;
}
double Perimeter() const override
{
return 2 * PI * radius;
}
void Print() const override
{
center.Print();
cout << "," << "r=" << radius << endl;
}
};
void fun(Shape &ref)
{
ref.Print();
cout << endl;
cout << "Area=" << ref.Area() << endl;
cout << "Perimeter=" << ref.Perimeter() << endl;
}
int main()
{
int x, y, r;
cin >> x >> y >> r;
Point p(x, y);
Circle c(x, y, r);
fun(p);
fun(c);
return 0;
}
抽象类和多态
【问题描述】画面设计公司,设计彩色图形,不同形状、不同颜色图形,需要统计红,蓝两种颜色的使用面积,以便购买绘制涂料。请设计图形类Figure,有color属性,求面积函数,返回颜色函数;定义子类矩形类,定义子类椭圆类。请用纯虚函数,多态实现。其中,PI用3.14,其他数值型用double,最后输出保留2位小数。
【输入形式】椭圆的数目
椭圆的短半轴,长半轴,颜色
…
矩形的数目
矩形的长,宽,颜色
…
【输出形式】每种颜色的面积
【样例输入】
2
3,4,r
5,6,b
3
6,7,r
8,9,r
4,7,b
【样例输出】
red area:151.68
blue area:122.20
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
class Figure
{ // 图形抽象类
protected:
char color[10];
public:
virtual double getArea() = 0;
virtual const char *getColor() = 0;
virtual ~Figure() {}
};
class Ellipse : public Figure
{ // 椭圆类
private:
double a;
double b;
public:
Ellipse(double a, double b, const char *color) : a(a), b(b)
{
strcpy(this->color, color);
}
double getArea() override
{
return 3.14 * a * b;
}
const char *getColor() override
{
return this->color;
}
};
class Rectangle : public Figure
{ // 矩形类
private:
double length;
double width;
public:
Rectangle(double length, double width, const char *color) : length(length), width(width)
{
strcpy(this->color, color);
}
double getArea() override
{
return length * width;
}
const char *getColor() override
{
return this->color;
}
};
int main()
{
int n;
cin >> n; // 输入椭圆的数目
double redArea = 0, blueArea = 0; // 初始化红蓝色面积
for (int i = 0; i < n; ++i)
{
double a, b;
char color[10];
scanf("%lf,%lf,%s", &a, &b, color);
Ellipse ellipse(a, b, color); // 创建椭圆对象
if (strcmp(ellipse.getColor(), "r") == 0)
{
redArea += ellipse.getArea(); // 累加红色面积
}
else if (strcmp(ellipse.getColor(), "b") == 0)
{
blueArea += ellipse.getArea(); // 累加蓝色面积
}
}
cin >> n; // 输入矩形的数目
for (int i = 0; i < n; ++i)
{
double length, width;
char color[10];
scanf("%lf,%lf,%s", &length, &width, color); // 输入矩形的长,宽,颜色
Rectangle rectangle(length, width, color); // 创建矩形对象
if (strcmp(rectangle.getColor(), "r") == 0)
{
redArea += rectangle.getArea(); // 累加红色面积
}
else if (strcmp(rectangle.getColor(), "b") == 0)
{
blueArea += rectangle.getArea(); // 累加蓝色面积
}
}
printf("red area:%.2lf\nblue area:%.2lf\n", redArea, blueArea); // 输出结果
return 0;
}
定义一个能够存储任何对象的链表类
【问题描述】采用模板技术定义一个能够存储任何对象的链表类,能够从键盘读入存储的数据类型、数据个数和数据列表,并按照输入顺序输出数据列表。
说明:
(1)0代表整型int; 1代表浮点型float 2代表字符串类型string.
(2)输入字符串类型时,可直接使用C++标准类库中的string类型。
(3)输入数据类型 不是 0,1,2三种时,输出error。
【输入形式】
数据类型 数据格式 数组元素
【输出形式】
数组元素 (浮点数保留一位小数)
【样例输入】
13
1 2 3
【样例输出】
1.0 2.0 3.0
【样例输入】
2 3
sam jake love
【样例输出】
sam jake love
【样例输入】
5 3
sam jake love
【样例输出】
error
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
// 链表类的前向声明
template <class T>
class list;
template <class T> // 声明模板
class node
{ // 定义结构模板
T val; // val取任意类型,即模板参数类型
node<T> *next; // 此处node为结构模板
public:
node()
{
next = NULL;
}
node(T a)
{
val = a;
next = NULL;
}
friend class list<T>;
};
// 请完成链表类的设计
template <class T>
class list
{
private:
node<T> *head;
public:
list()
{
head = NULL;
}
void insert(T val)
{
if (head == NULL)
{
head = new node<T>(val);
}
else
{
node<T> *current = head;
while (current->next != NULL)
{
current = current->next;
}
current->next = new node<T>(val);
}
}
void print()
{
node<T> *current = head;
while (current != NULL)
{
if (typeid(T) == typeid(int))
{
cout << current->val << " ";
}
else if (typeid(T) == typeid(float))
{
cout.setf(ios::fixed);
cout.precision(1);
cout << current->val << " ";
}
else if (typeid(T) == typeid(string))
{
cout << current->val << " ";
}
else
{
cout << "error";
return;
}
current = current->next;
}
cout << endl;
}
};
int main()
{
int kind = 0; // 0:表示整型,1:单精度浮点数, 2:字符串
int cnt = 0;
cin >> kind >> cnt;
// 整数链表
if (kind == 0)
{
list<int> intlist;
int nTemp = 0;
for (int i = 0; i < cnt; i++)
{
cin >> nTemp;
intlist.insert(nTemp);
}
intlist.print();
}
// 浮点数链表
else if (kind == 1)
{
list<float> floatlist;
float fTemp = 0;
cout.setf(ios::fixed);
cout.precision(1);
for (int i = 0; i < cnt; i++)
{
cin >> fTemp;
floatlist.insert(fTemp);
}
floatlist.print();
}
// 字符串链表
else if (kind == 2)
{
list<string> charlist;
char temp[100];
for (int i = 0; i < cnt; i++)
{
cin >> temp;
charlist.insert(temp);
}
charlist.print();
}
else
cout << "error";
return 0;
}
二维点Point对象的数组类 PointArray
【问题描述】
设计数组类 PointArray,用以存放例题中定义的Point类对象。
要求如下:
(1) 私有成员Point *pData,存放点类对象,size表示数组长度;
(2) 通过构造函数PointArray(int size)为数组分配空间;
(3) 通过析构函数,用以释放数组空间;
(4) 设计拷贝构造函数,用以数组复制;
【输入形式】
数组长度
x坐标 y坐标
【输出形式】
正序输出每个点的坐标
逆序输出每个点的坐标
【样例输入】
5
1 2
2 3
3 4
4 5
5 6
【样例输出】
元素:0的坐标为:x=1,y=2
元素:1的坐标为:x=2,y=3
元素:2的坐标为:x=3,y=4
元素:3的坐标为:x=4,y=5
元素:4的坐标为:x=5,y=6
倒序输出:
x=5,y=6
x=4,y=5
x=3,y=4
x=2,y=3
x=1,y=2
#include <iostream>
using namespace std;
class PointArray; // 前向声明
class Point
{
int x, y;
public:
// Point类的构造函数
Point(int x = 0, int y = 0) : x(x), y(y) {}
void SetX(int x) { this->x = x; }
void SetY(int y) { this->y = y; }
int GetX() { return x; }
int GetY() { return y; }
// 将PointArray声明为Point类的友元类
friend class PointArray;
// 通过友元方式重载输出运算符
friend ostream &operator<<(ostream &out, Point &pnt);
};
// 输出运算符重载
ostream &operator<<(ostream &out, Point &pnt)
{
cout << "x=" << pnt.x << ",y=" << pnt.y;
return cout;
}
class PointArray
{
Point *pData;
int size;
public:
explicit PointArray(int size);
~PointArray();
PointArray(const PointArray &src); // 拷贝构造函数
PointArray(PointArray &&src); // 移动构造函数
Point &operator[](int idx); // 重载下标运算符
PointArray &operator=(const PointArray &src); // 重载赋值运算符
PointArray &operator=(PointArray &&src) noexcept; // 移动赋值运算符
void Print(); // 打印函数
};
// 普通构造函数
PointArray::PointArray(int size)
{
this->size = size;
pData = new Point[size];
}
// 析构函数
PointArray::~PointArray()
{
delete[] pData;
}
// 拷贝构造函数
PointArray::PointArray(const PointArray &src)
{
size = src.size;
pData = new Point[src.size];
for (int i = 0; i < size; ++i)
{
pData[i] = src.pData[i];
}
}
// 移动构造函数
PointArray::PointArray(PointArray &&src)
{
pData = src.pData;
size = src.size;
src.pData = NULL;
src.size = 0;
}
// 重载下标运算符
Point &PointArray::operator[](int idx)
{
return pData[idx];
}
// 重载赋值运算符
PointArray &PointArray::operator=(const PointArray &src)
{
if (this != &src)
{
delete[] pData;
size = src.size;
pData = new Point[src.size];
for (int i = 0; i < size; ++i)
{
pData[i] = src.pData[i];
}
}
return *this;
}
// 移动赋值运算符
PointArray &PointArray::operator=(PointArray &&src) noexcept
{
if (this == &src)
return *this;
size = src.size;
if (this->pData != nullptr)
delete[] pData;
pData = src.pData;
src.pData = nullptr;
src.size = 0;
return *this;
}
void PointArray::Print()
{
if (size <= 0)
{
cout << "元素个数为0!" << endl;
return;
}
for (int i = 0; i < size; i++)
{
cout << "元素:" << i << "的坐标为:x=" << pData[i].x << ",y=" << pData[i].y << endl;
}
}
int main()
{
int count = 0;
cin >> count;
PointArray ar(count);
PointArray br(12);
int x, y;
for (int i = 0; i < count; i++)
{
cin >> x >> y;
ar[i].SetX(x);
ar[i].SetY(y);
}
// 输出数组元素
ar.Print();
br = ar;
if (count > 0)
{
cout << "倒序输出:" << endl;
for (int i = count - 1; i >= 0; i--)
cout << br[i] << endl;
}
}
Dog类和Cat类分别继承Animal类
【问题描述】Dog类和Cat类分别继承Animal类;
Animal类、Dog类和Cat类各有一个默认构造函数,分别输出字符串“Animal”,“Dog” 和“Cat”;一个析构函数;
在类中添加静态数据成员,用于运行时计算所有Animal,Dog和Cat类对象的数量;
在各类中添加静态函数成员getcount()函数,用于分别显示Animal,Dog和Cat类对象的数量;
在 Animal 类中定义纯虚函数 speak();在 Dog 和 Cat类中覆盖基类的 speak() 函数。
Dog类的speak函数输出字符串“wang”;Cat类的speak函数输出字符串“miao”。
主函数中,输入Dog数量n,Cat数量m;生成相关动物对象,显示数量变化情况;
【输入形式】输入Dog数量n,Cat数量m
【输出形式】生成相关动物对象,显示数量变化情况
【样例输入】
3
4
【样例输出】
Animal
Dog
Animal
Dog
Animal
Dog
Animal:3
Dog:3
Animal
Cat
Animal
Cat
Animal
Cat
Animal
Cat
Animal:7
Cat:4
wang
wang
wang
miao
Animal:3
Dog:0
Cat:3
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Animal
{
protected:
static int count;
public:
Animal()
{
cout << "Animal" << endl;
count++;
}
virtual ~Animal()
{
count--;
}
static void getcount()
{
cout << "Animal:" << count << endl;
}
virtual void speak() = 0;
};
int Animal::count = 0;
class Dog : public Animal
{
protected:
static int count;
public:
Dog()
{
cout << "Dog" << endl;
count++;
}
~Dog()
{
count--;
}
static void getcount()
{
cout << "Dog:" << count << endl;
}
void speak() override
{
cout << "wang" << endl;
}
};
int Dog::count = 0;
class Cat : public Animal
{
protected:
static int count;
public:
Cat()
{
cout << "Cat" << endl;
count++;
}
~Cat()
{
count--;
}
static void getcount()
{
cout << "Cat:" << count << endl;
}
void speak() override
{
cout << "miao" << endl;
}
};
int Cat::count = 0;
int main()
{
int n, m, i = 0;
cin >> n;
cin >> m;
Animal *a[20];
for (; i < n; i++)
{
a[i] = new Dog;
}
Animal::getcount();
Dog::getcount();
for (; i < n + m; i++)
{
a[i] = new Cat;
}
Animal::getcount();
Cat::getcount();
for (int j = 0; j < n + m - 3; j++)
{ // 总量小于3时,不做删除
a[j]->speak();
delete a[j];
a[j] = NULL;
}
Animal::getcount();
Dog::getcount();
Cat::getcount();
return 0;
}
今天的内容就分享这么多
求三连!!!
求关注!!!