本文为C++课程某一实验设计,考察对模板和泛型编程概念的理解和编程技能
知识点:模板和泛型编程
题目要求和功能如下:
(1)数组元素可动态实例化为int、double、string、Point等。
(2)类模板成员包括:数组长度、元素个数、数据指针。
(3)通过构造函数创建数组,默认包含10个元素,通过析构函数释放数组数据。
(4)追加数组元素:void AddItems(T aData[], int aLen); 在数组末尾添加aLen个元素,注意如果数组长度不够,需要动态扩展。
(5)删除数据元素:bool RemoveAt(int index); 返回是否删除成功。
(6)插入数组元素 void InsertItem( int index, T aData); 在数组的第index的位置插入元素aData,注意如果数组长度不够,需要动态扩展。
(7)数组元素排序,void mySort();
流程图如下(使用draw.io绘制)
代码如下:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <limits>
#include <sstream>
using namespace std;
template <class T>
class DynamicArray {
private:
int capacity;//V
int length;
T* temp;
public:
int GetLength() {
return length;
}
DynamicArray() {
capacity = 20;
length = 0;
temp = new T[capacity];
/* for (int i = 0; i < 10; i++) {
T element;
cin >> element;
temp[i] = element;
length++;
}*/
}
~DynamicArray() {
if (temp != NULL)
delete[] temp;
}
void AddItems(T aData[], int aLen);//末加aLen个元素,注意如果数组长度不够,需要动态扩展。
bool RemoveAt(int index); //返回是否删除成功
void InsertItem(int index, T aData); //第index的位置插入元素aData
void mySort();
void PrintArray();
};
template <class T>
void DynamicArray<T>::AddItems(T aData[], int aLen) {
if (length + aLen > capacity) {
capacity = max(capacity * 2, length + aLen);
T* newTemp = new T[capacity];//新建大
for (int i = 0; i < length; i++) {
newTemp[i] = temp[i];
}
delete[] temp;
temp = newTemp;
}
for (int i = 0; i < aLen; i++) {
temp[length++] = aData[i];
}
}
template <class T>
bool DynamicArray<T>::RemoveAt(int index) {//删除数组元素
if (index < 0 || index >= length) {
//printf("index不合理");
return false;
}
for (int i = index; i < length - 1; i++) {
temp[i] = temp[i + 1];
}
length--;
//cout << "删除成功" << endl;
return true;
}
//istream& operator>>(istream& in, T& data) {
// in >> data;
// return in;
//}
template <class T>
void DynamicArray<T>::InsertItem(int index, T aData) {
if (length + 1 >= capacity) {
capacity = capacity * 2;
T* newTemp = new T[capacity];
for (int i = 0; i < length; i++) {
newTemp[i] = temp[i];
}
delete[] temp;
temp = newTemp;
}
for (int i = length; i > index; i--) {
temp[i] = temp[i - 1];
}
temp[index] = aData;
//cout << "您在"<<index<<"处成功插入数据" <<aData<<"!" << endl;
length++;
//cout << "插入后的序列为:" <<endl;
//PrintArray();
}
//template <class T>
//void swap(T &a,T &b) {
// T* temp;
// temp = &a;
// &a = &b;
// &b = &temp;
//}
//template <class T>
//void Sort(T a[],int n) {//冒泡排序
// for(int i = n - 1;i > 0;i--)
// for (int j = 0; j < i; j++) {
// if (a[j] > a[j + 1])
// swap(a[j], a[j + 1]);
// }
//}
/***************************/
template <class T>
void DynamicArray<T>::mySort() {
sort(temp,temp+length);
/* for (int i = n - 1; i > 0; i--)
for (int j = 0; j < i; j++) {
if (a[j] > a[j + 1])
swap(a[j], a[j + 1]);
}*/
}
template <class T>
void DynamicArray<T>::PrintArray() {
cout << "当前处理过的序列是:";
for (int i = 0; i < length; i++) {
cout << temp[i] << " ";
}
cout << endl;
}
class Point {
public:
int x;
int y;
Point(int _x, int _y) : x(_x), y(_y) {}
Point() : x(0), y(0) {} // 默认构造函数
friend ostream& operator<<(ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
bool operator<(const Point& p) {
if (x == p.x) {
return y < p.y;
}
return x < p.x;
}
bool operator> (const Point& p) {
if (x == p.x) {
return y > p.y;
}
return x > p.x;
}
};
//增加对用户输入不是期待类型数据的判断
template <typename T>
bool isInputValid(const std::string& input) {
T temp;
std::istringstream iss(input);
return (iss >> temp) && iss.eof();
}
/******************主函数******************/
int main() {
int choice;
cout << "选择要实例化的类型: \n1. int\n2. string\n3. double\n4. Point\n";
cin >> choice;
//DynamicArray();
switch (choice) {
case 1: {
DynamicArray<int> intArray;
int* data = new int[20];
cout << "在最开始,请输入默认元素(10个): ";
for (int i = 0; i < 10; i++) {
string input;
cin >> input;
if (!isInputValid<int>(input)) {
cout << "输入类型错误,请重新输入int值: ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
i--;
}
else {
int value = stof(input);
data[i] = value;
}
}
for (int i = 0; i < 10; i++) {
cin >> data[i];
}
cout << "请输入要追加元素的数量: ";
int n;
cin >> n;
if (n + 10 > 20) {
cout << "输入数量超过容量上限,请重新输入或继续运行(请输入1重新输入,输入其他任意数字继续运行): ";
int choice;
cin >> choice;
if (choice == 1) {
cout << "输入元素的数量: ";
cin >> n;
}
}
cout << "请输入追加元素: ";
for (int i = 10; i < n+10; i++) {
cin >> data[i];
}
intArray.AddItems(data, n+10);
cout << "追加成功" << endl;
intArray.PrintArray();
/***************其他选择**************/
do {
cout << "请选择接下来要执行的操作" << endl;
cout << "1. 移除指定位置的元素\n2. 在指定位置插入元素\n3. 对数组进行排序\n4. 打印数组\n0. 退出\n";
cin >> choice;
switch (choice) {
case 1:
int index;
cout << "输入要移除的元素的位置(index): ";
cin >> index;
if (intArray.RemoveAt(index)) {
cout << "元素移除成功。" << endl;
intArray.PrintArray();
}
else {
cout << "无效位置。" << endl;
}
break;
case 2:
int insertIndex;
int value;
cout << "输入要插入的位置(index): ";
cin >> insertIndex;
cout << "输入要插入的值: ";
cin >> value;
intArray.InsertItem(insertIndex, value);
cout << "元素插入成功。" << endl;
intArray.PrintArray();
break;
case 3:
intArray.mySort();
cout << "数组已排序。" << endl;
intArray.PrintArray();
break;
case 4:
intArray.PrintArray();
break;
case 0:
cout << "程序退出。" << endl;
break;
default:
cout << "无效选项。请重试。" << endl;
}
} while (choice != 0);
delete[] data;
break;
}
/***********************string*****************************************/
case 2: {
DynamicArray<string> stringArray;
string* data = new string[20];
cout << "在最开始,请输入默认元素(10个): ";
for (int i = 0; i < 10; i++) {
string input;
cin >> input;
if (!isInputValid<string>(input)) {
cout << "输入类型错误,请重新输入string值: ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
i--;
}
else {
int value = stof(input);
data[i] = value;
}
}
cout << "请输入要追加元素的数量: ";
int n;
cin >> n;
if (n + 10 > 20) {
cout << "输入数量超过容量上限,请重新输入或继续运行(请输入1重新输入,输入其他任意数字继续运行): ";
int choice;
cin >> choice;
if (choice == 1) {
cout << "输入元素的数量: ";
cin >> n;
}
}
cout << "请输入追加元素: ";
for (int i = 10; i < n + 10; i++) {
cin >> data[i];
}
stringArray.AddItems(data, n + 10);
cout << "追加成功" << endl;
stringArray.PrintArray();
stringArray.AddItems(data, n);
stringArray.PrintArray();
/***************其他选择**************/
string value;//!!!!!!!!!!!!!!!
do {
cout << "1. 移除指定位置的元素\n2. 在指定位置插入元素\n3. 对数组进行排序\n4. 打印数组\n0. 退出\n";
cin >> choice;
switch (choice) {
case 1:
int index;
cout << "输入要移除的元素的位置(index): ";
cin >> index;
if (stringArray.RemoveAt(index)) {
cout << "元素移除成功。" << endl;
stringArray.PrintArray();
}
else {
cout << "无效位置。" << endl;
}
break;
case 2:
int insertIndex;
//string value;
cout << "输入要插入的位置(index): ";
cin >> insertIndex;
cout << "输入要插入的值: ";
cin >> value;
stringArray.InsertItem(insertIndex, value);
cout << "元素插入成功。" << endl;
stringArray.PrintArray();
break;
case 3:
stringArray.mySort();
cout << "数组已排序。" << endl;
stringArray.PrintArray();
break;
case 4:
stringArray.PrintArray();
break;
case 0:
cout << "程序退出。" << endl;
break;
default:
cout << "无效选项。请重试。" << endl;
}
} while (choice != 0);
delete[] data;
break;
}
case 3: {
DynamicArray<double> doubleArray;
double* data = new double[20];
cout << "在最开始,请输入默认元素(10个): ";
for (int i = 0; i < 2; i++) {
string input;
cin >> input;
if (!isInputValid<double>(input)) {
cout << "输入类型错误,请重新输入double值: ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
i--;
}
else {
int value = stof(input);
data[i] = value;
}
}
cout << "请输入要追加元素的数量: ";
int n;
cin >> n;
if (n + 10 > 20) {
cout << "输入数量超过容量上限,请重新输入或继续运行(请输入1重新输入,输入其他任意数字继续运行): ";
int choice;
cin >> choice;
if (choice == 1) {
cout << "输入元素的数量: ";
cin >> n;
}
}
cout << "请输入追加元素: ";
for (int i = 10; i < n + 10; i++) {
cin >> data[i];
}
doubleArray.AddItems(data, n + 10);
cout << "追加成功" << endl;
doubleArray.AddItems(data, n);
doubleArray.PrintArray();
do {
cout << "1. 移除指定位置的元素\n2. 在指定位置插入元素\n3. 对数组进行排序\n4. 打印数组\n0. 退出\n";
cin >> choice;
switch (choice) {
case 1:
int index;
cout << "输入要移除的元素的位置(index): ";
cin >> index;
if (doubleArray.RemoveAt(index)) {
cout << "元素移除成功。" << endl;
doubleArray.PrintArray();
}
else {
cout << "无效位置。" << endl;
}
break;
case 2:
int insertIndex;
double value;
cout << "输入要插入的位置(index): ";
cin >> insertIndex;
cout << "输入要插入的值: ";
cin >> value;
doubleArray.InsertItem(insertIndex, value);
cout << "元素插入成功。" << endl;
doubleArray.PrintArray();
break;
case 3:
doubleArray.mySort();
cout << "数组已排序。" << endl;
break;
case 4:
doubleArray.PrintArray();
break;
case 0:
cout << "程序退出。" << endl;
break;
default:
cout << "无效选项。请重试。" << endl;
}
} while (choice != 0);
delete[] data;
break;
}
case 4: {
int choice;///!
DynamicArray<Point> pointArray;
Point* pointData = new Point[20];
vector<Point> data;
cout << "在最开始,请输入默认元素(10个): ";
for (int i = 0; i < 10; i++) {
int x, y;
cin >> x >> y;
data.push_back(Point(x, y));
}
cout << "请输入要追加元素的数量: ";
int n;
cin >> n;
if (n + 10 > 20) {
cout << "输入数量超过容量上限,请重新输入或继续运行(请输入1重新输入,输入其他任意数字继续运行): ";
int choice;
cin >> choice;
if (choice == 1) {
cout << "输入元素的数量: ";
cin >> n;
}
}
cout << "请输入追加点的x和y坐标: ";
//vector<Point> data;
for (int i = 10; i < n + 10; i++) {
int x, y;
cin >> x >> y;
data.push_back(Point(x, y));
cout << "追加成功" << endl;
}
for (int i = 0; i < n+10; i++) {
pointData[i] = data[i];
}
n = n + 10;
pointArray.AddItems(pointData, n);
// pointArray.PrintArray();
do {
cout << "请选择你想实现的功能" << endl;
cout << "1. 移除指定位置的元素\n2. 在指定位置插入元素\n3. 对数组进行排序\n4. 打印数组\n0. 退出\n";
cin >> choice;
switch (choice) {
case 1:
int index;
cout << "输入要移除的元素的位置(index): ";
cin >> index;
if (pointArray.RemoveAt(index)) {
cout << "元素移除成功。" << endl;
pointArray.PrintArray();
}
else {
cout << "无效位置。" << endl;
}
break;
case 2:
int insertIndex, x, y;
cout << "输入要插入的位置(index): ";
cin >> insertIndex;
cout << "输入要插入的点的x和y坐标: ";
cin >> x >> y;
pointArray.InsertItem(insertIndex , Point(x, y));
cout << "元素插入成功。" << endl;
pointArray.PrintArray();
break;
case 3:
pointArray.mySort();
cout << "排序成功!" << endl;
pointArray.PrintArray();
break;
case 4:
pointArray.PrintArray();
break;
case 0:
cout << "程序退出。" << endl;
break;
default:
cout << "无效选项。请重试。" << endl;
}
} while (choice != 0);
delete[] pointData;
break;
}
default:
cout << "无效选项。程序退出。" << endl;
}
return 0;
}