目录
题目一:简单类模板(类模板)
题目二:矩阵类模板(类模板)
题目三:有界数组模板类(类模板)
题目四:OOP 多重收纳(类模板)
题目描述:
定义一个列表类,该列表包含属性:数值列表(用长度为100的数组表示),数据长度(实际的数据个数);包含的方法:初始化、插入、删除、打印,方法定义为:
1)初始化,接受外来参数,把数据保存在数值列表中,未使用的列表部分全部初始化为-1
2)插入,接受外来参数的插入位置和插入数值,插入位置从0开始计算,注意从插入位置开始,原有数据都要往后移动一位,且数据长度+1
3)删除,接受外来参数的删除位置,删除位置从0开始计算,注意从删除位置后一位开始,原有数据都要往前移动一位,且数据长度-1
4)打印,把包含的数据按位置顺序输出一行,数据之间单个空格隔开
使用类模板的方法,使得这个类支持整数int类型和浮点数double类型
输入要求:
第一行先输入参数n表示有n个数据,接着输入n个整数
第二行输入两个参数,表示插入位置和插入数值,数值为整数
第三行输入删除位置
第四行先输入参数n表示有n个数据,接着输入n个浮点数
第五行输入两个参数,表示插入位置和插入数值,数值为浮点数
第六行输入删除位置
输出要求:
针对头三行输入,分别执行初始化、插入操作和删除操作,调用打印方法输出列表包含的整数数据
针对接着的三行输入,分别执行初始化、插入操作和删除操作,调用打印方法输出列表包含的浮点数数据
输入样例:
5 11 22 33 44 55
2 888
4
5 1.1 2.2 3.3 4.4 5.5
2 88.8
3
输出样例:
11 22 888 33 55
1.1 2.2 88.8 4.4 5.5
代码示例:
#include
#include
#include
#include
#include
#include
using namespace std;
template//类模板
class List
{
private:
T number[100];
int num;
public:
List(int n)
{
for (int i = 0; i < n; i++)
{
cin >> number[i];
}
for (int i = n; i < 100; i++)
{
number[i] = -1;
}
num = n;
}
void insertList(int pos)
{
T dig;
cin >> dig;
for (int i = num; i > pos; i--)
{
number[i] = number[i - 1];
}
number[pos] = dig;
num++;
}
void deleteList(int pos)
{
for (int i = pos; i < num - 1; i++)
{
number[i] = number[i + 1];
}
number[num - 1] = -1;
num--;
}
void Print()
{
for (int i = 0; i < num; i++)
{
cout << number[i];
if (i != num - 1)
{
cout << " ";
}
else
{
cout << endl;
}
}
}
};
int main()
{
int n;
int pos1, pos2;
cin >> n;
List L1(n);;//;数据是int型
cin >> pos1;
L1.insertList(pos1);
cin >> pos2;
L1.deleteList(pos2);
L1.Print();
cin >> n;
List L2(n);//函数数据是
cin >> pos1;
L2.insertList(pos1);
cin >> pos2;
L2.deleteList(pos2);
L2.Print();
return 0;
}
类模板,故名思及就是模板,记住格式!
题目描述:
设计一个矩阵类模板Matrix,支持任意数据类型的数据。
要求至少包含2个成员函数:矩阵转置函数transport、以及打印输出函数print
编写main函数进行测试,调用类的成员函数完成转置和输出。
输入要求:
第一行先输入t,表示有t个测试用例
从第二行开始输入每个测试用例的数据。
首先输入数据类型,I表示int,D表示double,C表示char,接着输入两个参数m和n,分别表示矩阵的行和列
接下来输入矩阵的元素,一共m行,每行n个数据
输出要求:
输出转置后的矩阵
输入样例:
2
I 2 3
1 2 3
4 5 6
C 3 3
a b c
d e f
g h i
输出样例:
1 4
2 5
3 6
a d g
b e h
c f i
代码示例:
#include
#include
#include
#include
#include
#include
using namespace std;
template//类模板
class Matrix
{
private:
T** arr;
int row, col;
public:
Matrix(int rr, int cc) :row(rr), col(cc)
{
arr = new T * [row];
for (int i = 0; i < row; i++)
{
arr[i] = new T[col];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cin >> arr[i][j];
}
}
}
~Matrix()
{
delete arr;
}
void Transport()//矩阵转置
{
T** temp;
temp = new T * [col];
for (int i = 0; i < col; i++)
{
temp[i] = new T[row];
}
for (int i = 0; i < col; i++)
{
for (int j = 0; j < row; j++)
{
temp[i][j] = arr[j][i];
}
}
swap(row, col);
arr = new T * [row];
for (int i = 0; i < row; i++)
{
arr[i] = new T[col];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
arr[i][j] = temp[i][j];
}
}
}
void Print()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cout << arr[i][j];
if (j != col - 1)
{
cout << " ";
}
else
{
cout << endl;
}
}
}
}
};
int main()
{
int t;
cin >> t;
while (t--)
{
char type;
int rval, cval;
cin >> type >> rval >> cval;
if (type == 'I')
{
Matrix m1(rval, cval);//int类型矩阵
m1.Transport();
m1.Print();
}
else if (type == 'D')
{
Matrix m2(rval, cval);//double类型矩阵
m2.Transport();
m2.Print();
}
else if (type == 'C')
{
Matrix m3(rval, cval);//char类型矩阵
m3.Transport();
m3.Print();
}
}
return 0;
}
题目描述:
编写有界数组模板BoundArray(即检查对数组元素下标引用并在下标越界时终止程序的执行),能够存储各种类型的数据。要求实现对数组进行排序的方法sort,及对数组进行查找的方法search。(不能直接调用C++自带的排序或查找函数)
输入要求:
第一行先输入t,表示有t个测试用例
从第二行开始输入每个测试用例的数据。
首先输入数据类型,I表示int,D表示double,C表示char,接着输入数组的元素个数
然后输入每个元素
最后输入要查找的元素
输出要求:
首先输出从小到大排序的元素
然后输出查找元素的结果,找到则输出下标,没找到则输出-1
输入样例:
2
I 2
1 2
2
D 3
3.5 6.2 2.9
2.1
输出样例:
1 2
1
2.9 3.5 6.2
-1
代码示例:
#include
#include
#include
#include
#include
#include
using namespace std;
template//特定格式 template
class BoundArray
{
private:
T* arr;
int num;
public:
BoundArray(int nn) :num(nn)
{
arr = new T[num];
for (int i = 0; i < num; i++)
{
cin >> arr[i];
}
}
~BoundArray()
{
delete arr;
}
void Sort()
{
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
}
}
}
for (int i = 0; i < num; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void Search()
{
T target;
cin >> target;
bool mark = true;
for (int i = 0; i < num; i++)
{
if (arr[i] == target)
{
cout << i;
mark = false;
break;
}
}
if (mark)
{
cout << -1;
}
cout << endl;
}
};
int main()
{
int t;
cin >> t;
while (t--)
{
char type;
int n;
cin >> type >> n;
if (type == 'I')
{
BoundArray ba1(n);
ba1.Sort();
ba1.Search();
}
else if (type == 'D')
{
BoundArray ba2(n);
ba2.Sort();
ba2.Search();
}
else if (type == 'C')
{
BoundArray ba3(n);
ba3.Sort();
ba3.Search();
}
}
return 0;
}
题目描述:
现在我们要制作一种盒子,它能够收纳多种类型的元素,比如int、double、char、string等等。
我们每接收到一个数据都将它用这种盒子包装起来,然后放到同一个vector中。
为了能够包装不同类型的元素,我们决定用模板类来实现这种盒子,并起名为CBox.
然而,我们注意到CBox
为了能够放到一个vector中,我们决定为CBox模板类定义一个抽象父类CBoxObject。
这样我们就能利用父类指针将不同的CBox实例类对象集中放到一个vector
下面给出CBoxObject抽象类的定义:(不可修改)
class CBoxObject {
protected:
string type; // 记录类型信息
public:
CBoxObject(string _type) : type(_type) {}
virtual void show(ostream&) const = 0; // 用于输出信息
};
为了查看vector中任意盒子的数据,我们决定采用多态的技术来实现:
1. 要求CBox模板类继承CBoxObject类,并且要定义一个成员变量;
2. CBox要实现父类虚函数void show(ostream&),show函数将信息输出到ostream中,
1) 一般输出格式为:{type: value}
2) 如果元素为空指针,则输出为:{}
3. 为CBox模板类添加void setVal(T _val)函数,以便于修改数据
下面给出测试主函数如下:(不可修改)
template
void pushBox(istream& in, vector
T val;
in >> val;
container.emplace_back(new CBox
}
int main() {
string type; // 数据类型
int n, index; // n为输入次数,index为vector数组下标
cin >> n;
vector
pBoxes.reserve(n); // 预先分配足够的空间(pBoxes.size()==0依然成立)
while (n-- > 0) {
cin >> type;
// 根据数据类型分别包装
if (type == "char") pushBox
else if (type == "int") pushBox
else if (type == "double") pushBox
else if (type == "string") pushBox
// 我们觉得一个盒子也是可以包装另一个盒子的
// 为了便捷起见,我们采用盒子指针来表示盒子间的包装关系
else if (type == "box") {
cin >> index;
auto box = new CBox
// 根据index从pBoxes已有的盒子中选择一个用新盒子包装
if (0 <= index && index < pBoxes.size()) {
box->setVal(pBoxes[index]);
// 现实中盒子是不能自己包装自己的
// 在本题中,如果盒子自己包装自己,则将指针值设置为空
// 本题暂不考虑链表成环问题
}
pBoxes.emplace_back(box);
}
index = (int)pBoxes.size() - 1;
cout << *pBoxes[index] << endl;
}
for (CBoxObject*& box : pBoxes) delete box;
return 0;
}
在决定使用CBoxObject*原生指针类型作为CBox的模板参数时,你可能会发现一个问题:
a)如果包装的值是"空指针nullptr"(NULL倒不会),则在输出时会出现问题!
b)如果包装值是非空指针,那么一般来说打印指针值是没有什么价值的,我们更关注的是指针所指向的内容。
我们希望能够对T*这样的模板参数类型定义不同处理方式。
通过进一步学习可以了解到c++支持的"模板偏特化"方法:
template
template
template
......
4. 为CBox模板类定义适合以原生指针作为模板参数的特化版本
由于定义的成员变量为指针类型,且同一对象被new出来后可能被赋予多个所有者,
为了简化编程,本题不考虑析构函数(使用默认的即可)
(要进一步保障复制和析构安全性,避免内存泄露,可以考虑加入"引用计数指针"进一步完善定义,本题目不作要求)
本题的特化版本为:
template <>
class CBox
{
CBoxObject *data;
在处理输出时,你可能会写出"cout< 如果使用了CBox 5. 为CBoxObject类重载输出 输入要求: 参见主函数 输出要求: 输出格式:{type: value} 如果为value为空指针(nullptr),则输出为:{} 输入样例: 输出样例: 代码示例: 最后一题感觉参考意义不大10
string hello
int 666
char c
double 3.14
box 3
box 4
box 6
box 6
box 9
box -1
{string: hello}
{int: 666}
{char: c}
{double: 3.14}
{box: {double: 3.14}}
{box: {box: {double: 3.14}}}
{}
{box: {}}
{}
{}
#include