A. 有界数组模板类(类模板)
题目描述
编写有界数组模板BoundArray
(即检查对数组元素下标引用并在下标越界时终止程序的执行),能够存储各种类型的数据。要求实现对数组进行排序的方法sort
,及对数组进行查找的方法search
。
输入
第一行先输入t,表示有t个测试用例
从第二行开始输入每个测试用例的数据。
首先输入数据类型,I
表示int
,D
表示double
,C
表示char
,接着输入数组的元素个数
然后输入每个元素
最后输入要查找的元素
输出
首先输出从小到大排序的元素
然后输出查找元素的结果,找到则输出下标,没找到则输出-1
输入样例1
2
I 2
1 2
2
D 3
3.5 6.2 2.9
2.1
输出样例1
1 2
1
2.9 3.5 6.2
-1
AC代码
#include<bits/stdc++.h>
using namespace std;
template<class T>
class BoundArray {
int size;
T* p;
public:
BoundArray() {
cin >> size;
p = new T[size];
for (int i = 0; i < size; i++)
cin >> p[i];
}
~BoundArray()
{
delete[]p;
}
void sort() {
make_heap(p, p + size);
sort_heap(p, p + size);
}
int search(T key) {
for (int i = 0; i < size; i++) {
if (key == p[i])
return i;
}
return -1;
}
void print() {
for (int i = 0; i < size; i++)
cout << p[i] << " ";
cout << endl;
}
};
int main() {
int t;
cin >> t;
while (t--)
{
char ch;
cin >> ch;
if (ch == 'I') {
BoundArray<int>l;
l.sort();
l.print();
int key;
cin >> key;
cout << l.search(key) << endl;
}
else if (ch == 'D') {
BoundArray<double>l;
l.sort();
l.print();
double key;
cin >> key;
cout << l.search(key) << endl;
}
else if (ch == 'C') {
BoundArray<char>l;
l.sort();
l.print();
char key;
cin >> key;
cout << l.search(key) << endl;
}
}
return 0;
}
B. 简单类模板(类模板)
题目描述
定义一个列表类,该列表包含属性:数值列表(用长度为100的数组表示),数据长度(实际的数据个数);包含的方法:初始化、插入、删除、打印,方法定义为:
1)初始化,接受外来参数,把数据保存在数值列表中,未使用的列表部分全部初始化为-1
2)插入,接受外来参数的插入位置和插入数值,插入位置从0开始计算,注意从插入位置开始,原有数据都要往后移动一位,且数据长度+1
3)删除,接受外来参数的删除位置,删除位置从0开始计算,注意从删除位置后一位开始,原有数据都要往前移动一位,且数据长度-1
4)打印,把包含的数据按位置顺序输出一行,数据之间单个空格隔开
使用类模板的方法,使得这个类支持整数int
类型和浮点数double
类型
输入
第一行先输入参数n表示有n个数据,接着输入n个整数
第二行输入两个参数,表示插入位置和插入数值,数值为整数
第三行输入删除位置
第四行先输入参数n表示有n个数据,接着输入n个浮点数
第五行输入两个参数,表示插入位置和插入数值,数值为浮点数
第六行输入删除位置
输出
针对头三行输入,分别执行初始化、插入操作和删除操作,调用打印方法输出列表包含的整数数据
针对接着的三行输入,分别执行初始化、插入操作和删除操作,调用打印方法输出列表包含的浮点数数据
输入样例1
5 11 22 33 44 55
2 888
4
5 1.1 2.2 3.3 4.4 5.5
2 88.8
3
输出样例1
11 22 888 33 55
1.1 2.2 88.8 4.4 5.5
#include<bits/stdc++.h>
using namespace std;
template<class T>
class List {
vector<T>v;
public:
List() {
int len;
cin >> len;
v.resize(len);
for (auto& it : v)
cin >> it;
}
void insert(int index, T value) {
v.insert(v.begin() + index, value);
}
void remove(int index) {
v.erase(v.begin() + index);
}
void print() {
for (int i = 0; i < v.size(); i++) {
if (i)
cout << " ";
cout << v[i];
}
cout << endl;
}
};
int main() {
List<int>l1;
int idx, value;
cin >> idx >> value;
l1.insert(idx, value);
cin >> idx;
l1.remove(idx);
l1.print();
List<double>l2;
int idx1;
double value1;
cin >> idx1 >> value1;
l2.insert(idx1, value1);
cin >> idx1;
l2.remove(idx1);
l2.print();
return 0;
}
C. 矩阵类模板(类模板)
题目描述
设计一个矩阵类模板Matrix,支持任意数据类型的数据。
要求至少包含2个成员函数:矩阵转置函数transport、以及打印输出函数print
编写main函数进行测试,调用类的成员函数完成转置和输出。
输入
第一行先输入t,表示有t个测试用例
从第二行开始输入每个测试用例的数据。
首先输入数据类型,I表示int,D表示double,C表示char,接着输入两个参数m和n,分别表示矩阵的行和列
接下来输入矩阵的元素,一共m行,每行n个数据
输出
输出转置后的矩阵
输入样例1
2
I 2 3
1 2 3
4 5 6
C 3 3
a b c
d e f
g h i
输出样例1
1 4
2 5
3 6
a d g
b e h
c f i
AC代码
#include<bits/stdc++.h>
using namespace std;
template<class T>
class Matrix {
vector<vector<T>>v;
int n, m;
public:
Matrix() {
cin >> n >> m;
v.resize(n);
for (int i = 0; i < n; i++)
v[i].resize(m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> v[i][j];
}
void transport() {
vector<vector<T>>v1;
v1.resize(m);
for (int i = 0; i < m; i++)
v1[i].resize(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
v1[j][i] = v[i][j];
v = v1;
swap(n, m);
}
void print() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j)cout << " ";
cout << v[i][j];
}
cout << endl;
}
}
};
int main() {
int t;
cin >> t;
while (t--)
{
char ch;
cin >> ch;
if (ch == 'I') {
Matrix<int>m;
m.transport();
m.print();
}
else if (ch == 'D') {
Matrix<double>m;
m.transport();
m.print();
}else if (ch == 'C') {
Matrix<char>m;
m.transport();
m.print();
}
}
return 0;
}
D. 排序函数模板
题目描述
编写一个对n个元素的数组升序排序的函数模板mysort,其中元素类型可以是基本数据类型,也可以是点对象(按点到原点的距离比较)。(要求不能用C++提供的sort函数模板)
输入
第一行输入测试次数
每次测试输入二行,第1行先输入一个大写字母表示数组类型,I表示整数类型,S表示字符串型,D表示双精度数类型,P表示点,最后输入n表示数组长度。第2行输入n个数据。
输出
每次测试输出一行排序后的结果
输入样例1
4
I 10
15 3 51 27 9 35 78 14 65 8
D 3
-11.3 25.42 13.2
P 6
1.1 2.2 2.4 -6.5 12 32 1.2 1.3 -3.5 0.1 9.2 1.1
S 4
sandy david eason cindy
输出样例1
3 8 9 14 15 27 35 51 65 78
-11.3 13.2 25.42
(1.2, 1.3) (1.1, 2.2) (-3.5, 0.1) (2.4, -6.5) (9.2, 1.1) (12.0, 32.0)
cindy david eason sandy
AC代码
#include<bits/stdc++.h>
using namespace std;
template<class T>
class MySort;
class Point {
double x, y;
template<class T>
class MySort;
public:
Point() {}
double getDistance() const {
return sqrt(x * x + y * y);
}
bool operator <(const Point& p)const {
return getDistance() < p.getDistance();
}
friend ostream& operator << (ostream& output, Point& p) //定义运算符“<<”重载函数
{
output << fixed << setprecision(1) << "(" << p.x << ", " << p.y << ")";
return output;
}
friend istream& operator >> (istream& input, Point& p) //定义运算符“<<”重载函数
{
input >> p.x >> p.y;
return input;
}
};
template<class T>
class MySort {
vector<T>v;
class Point;
public:
MySort() {
int size;
cin >> size;
v.resize(size);
for (auto& it : v) {
cin >> it;
}
make_heap(v.begin(), v.end());
sort_heap(v.begin(), v.end());
for (int i = 0; i < size; i++) {
cout << v[i] << " ";
}
cout << endl;
}
};
int main() {
int t;
cin >> t;
while (t--)
{
char ch;
cin >> ch;
if (ch == 'I') {
MySort<int>s;
}
else if (ch == 'D') {
MySort<double>s;
}
else if (ch == 'S') {
MySort<string>s;
}
else if (ch == 'P') {
MySort<Point>s;
}
}
return 0;
}
E. 对象相加函数模板
题目描述
时钟类CClock有时、分、秒;人民币类CRmb有元、角、分三个数据成员。试为这种类型的类对象定义一个两两相加的函数模板add,包括三个参数:2个对象和一个int表示进制。(要求不能用函数重载的方法)
主函数如下所示:
…
CClock c1(…), c2(…), c;
c = add(c1, c2, 60);
cout << c << endl;
CRmb r1(…), r2(…), r;
r = add(r1, r2, 10);
cout << r << endl;
输入
第一个时钟对象的时分秒
第二个时钟对象的时分秒
第一个人民币对象的元角分
第二个人民币对象的元角分
输出
两个时钟对象相加的结果
两个人民币对象相加的结果
输入样例1
15 34 25
7 25 36
5 6 7
3 4 5
输出样例1
23 0 1
9 1 2
AC代码
#include<bits/stdc++.h>
using namespace std;
class CClock {
int h, m, s;
public:
CClock() {
cin >> h >> m >> s;
}
CClock(int h, int m, int s) :
h(h),
m(m),
s(s) {}
template<class T>
friend T add(T, T, int);
int getSumSecond(int n) {
return s + m * n + h * n * n;
}
friend CClock add(CClock& a, CClock& b, int n) {
int sum = a.getSumSecond(n) + b.getSumSecond(n);
int hour = sum / (n * n);
sum = sum % (n * n);
int minu = sum / n;
int sece = sum % n;
return CClock(hour, minu, sece);
}
void print() {
cout << h << " " << m << " " << s;
}
friend ostream& operator << (ostream& output, CClock& p) //定义运算符“<<”重载函数
{
p.print();
return output;
}
};
class RMB {
int y, j, f;
public:
RMB(int y, int j, int f) :y(y), j(j), f(f)
{
}
RMB() { cin >> y >> j >> f; }
int getSumFen(int n) {
return f + j * n + y * n * n;
}
friend RMB add(RMB& a, RMB& b, int n) {
int sum = a.getSumFen(n) + b.getSumFen(n);
int hour = sum / (n * n);
sum = sum % (n * n);
int minu = sum / n;
int sece = sum % n;
return RMB(hour, minu, sece);
}
void print() {
cout << y << " " << j << " " << f;
}
friend ostream& operator << (ostream& output, RMB& p) //定义运算符“<<”重载函数
{
p.print();
return output;
}
template<class T>
friend T add(T, T, int);
};
template<class T>
T add(T a, T b, int n) {
return add(a, b, n);
}
int main() {
CClock c1, c2;
CClock c = add(c1, c2, 60);
cout << c << endl;
RMB r1, r2;
RMB r = add(r1, r2, 10);
cout << r << endl;
return 0;
}
F. 逆序输出函数模板
题目描述
编写一个逆序输出数据的函数模板reverse(复数的逆序是实部虚部置换)。
输入
第一行输入测试次数
每次测试输入一行,先输入一个大写字母表示数据类型, I表示整型、D表示双精度型、S表示string类型字符串、C表示复数类对象,最后输入数据。
输出
每次测试输出一行,逆序排列的数据
输入样例1
5
I 123456
D -235.172
S thisisatest
C -123 456
C 123 -456
输出样例1
654321
-271.532
tsetasisiht
456-123
-456+123
提示
可用类型转换函数将复数类对象转换为string.模板函数内采用如下所示的方法可将数值型变量a转换成string型变量s:#include “sstream”…ostringstream os;string s; os << a; s = os.str();
#include<bits/stdc++.h>
using namespace std;
class Complex {
double r, i;
public:
Complex() { cin >> r >> i; }
friend ostream& operator<<(ostream& output, Complex& c) {
output << c.r;
if (!c.i)
return output;
if (c.i > 0)
cout << "+";
cout << c.i;
return output;
}
friend istream& operator>>(istream& input, Complex& c) {
input >> c.r >> c.i;
return input;
}
friend void reverse(Complex&c) {
swap(c.r, c.i);
cout << c << endl;
}
};
template<class T>
void reverse(T t) {
string s = to_string(t);
//if (typeid(t) == typeid(double)) {
// while (*s.rbegin()=='0'){
// s.pop_back();
// }
//}
reverse(s.begin(), s.end());
if (*s.rbegin() == '-') {
s.pop_back();
cout << "-";
}
if (typeid(t) == typeid(int)) {
cout << stoi(s) << endl;
return;
}
if (typeid(t) == typeid(double)) {
cout << stod(s) << endl;
return;
}
cout << s << endl;
}
void reverse(string &s) {
reverse(s.begin(), s.end());
cout << s << endl;
}
int main() {
int t;
cin >> t;
while (t--)
{
char ch;
cin >> ch;
string t1;
if (ch == 'I') {
int t1;
cin >> t1;
reverse<int>(t1);
}
else if (ch == 'D') {
double t1;
cin >> t1;
reverse<double>(t1);
}
else if (ch == 'S') {
string t1;
cin >> t1;
reverse(t1);
}
else {
Complex t1;
reverse(t1);
}
}
}
G. 链表类模板
题目描述
结点数据类型为int的单链表类CIntList可定义如下:
class CNode
{
public:
int data;
CNode *next;
};
class CIntList
{
private:
CNode *head;
public:
CIntList();
void append(int a); //加到链表最后
void insert(int a, int n); //在第n个结点后加
void remove(int n); //移除第n个结点
int get(int n); //返回第n个结点的数据
void set(int a, int n); //将第n个节点的数据改成a
void print();
~CIntList();
};
试将其改成结点数据类型用参数表示的类模板CList。
输入
第一行输入测试次数
每次测试输入5行,格式为:
数据类型(I:int, D:double, S:string) 数据个数n 数据1 数据2 … 数据n
插入节点号(0表示插在第1个结点前面) 数据
返回结点号
删除结点号
修改结点号 数据
输出
每次测试输出二行.第1行输出返回操作获得的数据(如出错则输出error),第2行输出所有操作后链表全部结点的数据.
输入样例1
3
I 5 2 3 5 7 3
1 40
7
7
6 -10
D 6 1.1 2.3 10.05 0.0 -1.8 5.9
4 60.4
5
1
3 -3.7
S 4 this is a test.
0 good
1
8
4 work
输出样例1
error
2 40 3 5 7 -10
60.4
2.3 10.05 -3.7 60.4 -1.8 5.9
good
good this is work test.
AC代码
#include<bits/stdc++.h>
using namespace std;
template<class T>
struct CNode
{
T data;
CNode<T>* next;
CNode() { next = NULL; }
CNode(T d, CNode<T>* n = NULL) {
data = d;
next = n;
}
};
template<class T>
class List {
int len;
CNode<T>* head;
public:
List() {
cin >> len;
head = new CNode<T>;
CNode<T>* p = head;
for (int i = 0; i < len; i++) {
p->next = new CNode<T>;
p = p->next;
cin >> p->data;
}
}
void append(T a) {
CNode<T>p = head;
while (p) {
p = p->next;
}
p = new CNode<T>(a);
len++;
}
void insert(T a, int n) {
if (n < 0 || n > len)
return;
CNode<T>* p = head;
for (int i = 0; i < n; i++) {
p = p->next;
}
CNode<T>* s = new CNode<T>(a, p->next);
p->next = s;
len++;
}
void remove(int n) {
if (n < 0 || n >= len)
return;
CNode<T>* p = head;
for (int i = 0; i < n; i++) {
p = p->next;
}
CNode<T>* s = p->next;
p->next = s->next;
delete s;
len--;
}
void set(T a, int n) {
if (n < 0 || n >= len)
return;
CNode<T>* p = head->next;
for (int i = 0; i < n; i++) {
p = p->next;
}
p->data = a;
}
void print() {
CNode<T>* p;
for (p = head->next; p->next; p = p->next)
cout << p->data << " ";
cout << p->data << endl;
}
T get(int n) {
CNode<T>* p = head->next;
for (int i = 0; i < n; i++)
p = p->next;
return p->data;
}
int getSize() { return len; }
};
int main() {
int t;
cin >> t;
while (t--)
{
char ch;
cin >> ch;
if (ch == 'I') {
List<int>l;
int a;
int n;
cin >> n >> a;
l.insert(a, n);
cin >> n;
if (n<1 || n>l.getSize()) {
puts("error");
}
else {
cout << l.get(n - 1) << endl;
}
cin >> n;
l.remove(n - 1);
cin >> n >> a;
l.set(a, n - 1);
l.print();
}
else if (ch == 'D') {
List<double>l;
double a;
int n;
cin >> n >> a;
l.insert(a, n);
cin >> n;
if (n<1 || n>l.getSize()) {
puts("error");
}
else {
cout << l.get(n - 1) << endl;
}
cin >> n;
l.remove(n - 1);
cin >> n >> a;
l.set(a, n - 1);
l.print();
}
else if (ch == 'S') {
List<string>l;
string a;
int n;
cin >> n >> a;
l.insert(a, n);
cin >> n;
if (n<1 || n>l.getSize()) {
puts("error");
}
else {
cout << l.get(n - 1) << endl;
}
cin >> n;
l.remove(n - 1);
cin >> n >> a;
l.set(a, n - 1);
l.print();
}
}
}