目录
函数接口定义:sort函数将接受size个数据,将它们从小到大排序后存在a指向的一段连续空间中。
前言 老规矩,强者直接转源代码
题目
6-1
实现一个类模板,它可以接受一组数据,能对数据排序,也能输出数组的内容。
每行输入的第一个数字为0,1,2或3:为0时表示输入结束; 为1时表示将输入整数,为2时表示将输入有一位小数的浮点数,为3时表示输入字符。
如果第一个数字非0,则接下来将输入一个正整数,表示即将输入的数据的数量。
从每行第三个输入开始,依次输入指定类型的数据。
类模板:
template <class T> class MyArray
裁判测试程序样例:
#include <iostream>
using namespace std;
/* 请在这里填写答案 */
template<class T>
MyArray<T>::~MyArray(){ delete[] data;}
template<class T>
bool MyArray<T>::check(){
int i;
for(i=0;i<size-1;i++)
if(data[i]>data[i+1]) { cout<<"ERROR!"<<endl;return false;}
return true;
}
int main( )
{
MyArray<int> *pI;
MyArray<float> *pF;
MyArray<char> *pC;
int ty, size;
cin>>ty;
while(ty>0){
cin>>size;
switch(ty){
case 1: pI = new MyArray<int>(size); pI->sort(); pI->check(); pI->display(); delete pI; break;
case 2: pF = new MyArray<float>(size); pF->sort(); pF->check(); pF->display(); delete pF; break;
case 3: pC = new MyArray<char>(size); pC->sort(); pC->check(); pC->display(); delete pC; break;
}
cin>>ty;
}
return 0;
}
输入样例:
1 3 2 3 1
2 4 1.5 2.6 3.7 0.5
3 2 A a
0
输出样例:
1 2 3
0.5 1.5 2.6 3.7
A a
6-2
对于输入的每一批数,按从小到大排序后输出。
一行输入为一批数,第一个输入为数据类型(1表示整数,2表示字符型数,3表示有一位小数的浮点数,4表示字符串,0表示输入结束),第二个输入为该批数的数量size(0<size<=10),接下来为size个指定类型的数据。
输出将从小到大顺序输出数据。
函数接口定义:sort函数将接受size个数据,将它们从小到大排序后存在a指向的一段连续空间中。
template <class T> void sort(T *a, int size);
裁判测试程序样例:
#include <iostream>
#include <string>
using namespace std;
/* 请在这里填写答案 */
template <class T>
void display(T* a, int size){
for(int i=0; i<size-1; i++) cout<<a[i]<<' ';
cout<<a[size-1]<<endl;
}
int main() {
const int SIZE=10;
int a[SIZE];
char b[SIZE];
double c[SIZE];
string d[SIZE];
int ty, size;
cin>>ty;
while(ty>0){
cin>>size;
switch(ty){
case 1:sort(a,size); display(a,size); break;
case 2:sort(b,size); display(b,size); break;
case 3:sort(c,size); display(c,size); break;
case 4:sort(d,size); display(d,size); break;
}
cin>>ty;
}
return 0;
}
输入样例:
1 3 3 2 1
2 2 a A
3 3 1.5 2.6 2.2
4 2 bca abc
0
输出样例:
1 2 3
A a
1.5 2.2 2.6
abc bca
6-3
本题要求实现一个Vector类模板,能实现数据的存储和访问。通过[]
运算符访问时只能访问已经存在的元素,而通过add()
方法访问时可以自动扩展内部存储空间。
注意,这个Vector
的行为和std::vector
是不同的
函数接口定义:
template <class T> class Vector { ...
裁判测试程序样例:
#include <iostream>
using namespace std;
/* 请在这里填写答案 */
int main()
{
Vector<int> vint;
int n,m;
cin >> n >> m;
for ( int i=0; i<n; i++ ) {
// add() can inflate the vector automatically
vint.add(i);
}
// get_size() returns the number of elements stored in the vector
cout << vint.get_size() << endl;
cout << vint[m] << endl;
// remove() removes the element at the index which begins from zero
vint.remove(m);
cout << vint.add(-1) << endl;
cout << vint[m] << endl;
Vector<int> vv = vint;
cout << vv[vv.get_size()-1] << endl;
vv.add(m);
cout << vint.get_size() << endl;
}
输入样例:
100 50
输出样例:
100
50
99
51
-1
100
6-4
完善Square
的定义,使得程序正确运行:
裁判测试程序样例:
#include <iostream>
using namespace std;
// 请将答案填写在这里
int main() {
int width1;
cin >> width1; // 输入正方形的边长
Square<int> square1(width1);
cout << square1.getArea() << endl; // 输出正方形的面积
double width2;
cin >> width2; // 输入正方形的边长
Square<double> square2(width2);
cout << square2.getArea() << endl; // 输出正方形的面积
return 0;
}
输入样例:
在这里给出一组输入。例如:
3
1.1
输出样例:
在这里给出相应的输出。例如:
9
1.21
解析
这边头文件我就不写了,可以先都用<iostream>看看报错缺啥
要是实在有人找不出来用什么(不会吧不会吧),那就<bits/stdc++.h>
6-1 有序数组(类模板)
template <class T>
class MyArray
{
public:
bool check();
~MyArray();
MyArray(int);
void sort();
void display();
private:
int size;
T* data;
};
bool check(); 一个用来检查数组的方法
~MyArray(); 析构函数,用来释放对象占用的内存
MyArray(int); 构造函数,用来初始化数组,需要传入数组的大小作为参数
void sort(); 一个用来对数组进行排序的方法
void display(); 一个用来显示数组内容的方法
T* data; 一个指向模板类型 T
的指针,用来存储数组的数据
类里面的函数就叫做方法
我个人的习惯是看完题之后,把要用的函数都声明一下(最后在去掉嘛),不过先写功能再声明也无所谓了,仁者见仁智者见智吧
template<class T>
MyArray<T>::MyArray(int s)
{
size=s;
data=new T[size];
for(int i=0;i<size;i++)
cin>>data[i];
}
这段代码是类模板 MyArray
的构造函数 MyArray(int s)
的实现部分。在这里,template<class T>
表示这是类模板 MyArray
的成员函数。
在构造函数中,传入一个整数参数 s
,表示数组的大小。然后,将类中的 size
成员变量设置为传入的大小 s
。接着,使用 new
(申请的堆上的空间,咱们一般直接申请的都是栈上的)(栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;)运算符动态分配了一个大小为 size
的类型为 T
的数组,并将指针赋值给类中的 data
成员变量。
然后,使用一个循环遍历数组,通过 cin
从标准输入中依次输入数组中的元素。每次循环,将输入的元素存储到数组的对应位置 data[i]
中。
总之,这段代码实现了类模板 MyArray
的构造函数,用于动态分配存储空间并从标准输入中读取数据存储到数组中。
template<class T>
void MyArray<T>::display()
{
for(int i=0; i<size-1; i++) cout<<data[i]<<' ';
cout<<data[size-1]<<endl;
}
这段代码是类模板 MyArray
的成员函数 display()
的实现部分。template<class T>
表示的跟上面那个意思一样哈。
使用一个循环遍历数组,从下标 0
到 size-1
,输出数组中的元素到标准输出流 cout
中,每个元素之间用空格分隔。(注意上下两段中这两个size-1的含义是不一样的)
循环结束后,再输出数组中最后一个元素 data[size-1]
到标准输出流 cout
中,然后换行。
总之,这段代码实现了类模板 MyArray
的成员函数 display()
,用于在标准输出中显示数组中的元素。
template<class T>
void MyArray<T>::sort()
{
for(int i=0; i<size; i++)
{
int min=i;
for(int j=i+1; j<size; j++)
{
if(data[min]>data[j])
{
min=j;
}
}
if(min!=i)
{
T temp=data[min];
data[min]=data[i];
data[i]=temp;
}
}
}
这是一个插入排序哈,换成冒泡和选择也是whatever的,注意temp的类型是T就行了
6-2 数组排序输出(函数模板)
template <class T>
void sort(T *arr, int size)
{
for(int i=0;i<size;i++)
{
cin>>arr[i];
}
/*
for(int i=0; i<size; i++)
{
int min=i;
for(int j=i+1; j<size; j++)
{
if(a[min]>a[j])
{
min=j;
}
}
if(min!=i)
{
T temp=a[min];
a[min]=a[i];
a[i]=temp;
}
}
*/
int j,i;
T tem;
for (i = 0; i < size-1;i ++)//size-1是因为不用与自己比较,所以比的数就少一个
{
int count = 0;
for (j = 0; j < size-1 - i; j++) //size-1-i是因为每一趟就会少一个数比较
{
if (arr[j] > arr[j+1])//这是升序排法,前一个数和后一个数比较,如果前数大则与后一个数换位置
{
tem = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tem;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
这边注释里面的排序方法也是可以直接用的,建议是各种排序方法都自己写一遍,这个还没6-1难,6-1理解了,这个简单的跟喝水一样,所以我就不多赘述喽。
6-3 vector
template <class T>
class Vector
{
int tos=0; //创建一个整数用于下标表示
const int size=100; //创建一个常数用于表示动态申请空间大小
T*data; //定义一个指针,用于动态申请空间
public:
Vector() //构造函数动态申请空间
{
data=new T[size];
}
data=new T[size]; 就是在堆上开辟一个名为data的动态数组
int add(int i)
{
//data=new T[size]; //不能在add函数里申请空间,因为作用域小了,add函数结束空间就被自己注销了
data[tos]=i; //存入数组
tos++;
return tos-1; //返回tos-1是根据main函数结果来的
}
这个函数用于向数组中添加一个新的元素 i
。
在函数内部,首先将元素 i
存储到数组的 tos
位置(tos
是一个表示下一个可用位置的索引),然后递增 tos
,最后返回 tos-1
,表示添加的元素的索引。
int get_size()
{
return tos; //下标就代表了数组大小
}
这个函数用于返回数组的大小,即 tos
的值。
因为 tos
表示下一个可用位置的索引,所以它也代表了数组的大小。
void remove(int m)
{
for(int i=m; i<tos-1; i++) //移除某个值后后面的值需要填补上,
{
data[i]=data[i+1];
}
tos--;
}
这个函数用于移除数组中的某个元素。
在函数内部,通过循环将索引大于等于 m
的元素向前移动一位,然后递减 tos
。
const T& operator[](int i)//重载了[]运算符
{
return data[i];
}
};
这个函数是重载了 []
运算符,用于通过索引访问数组中的元素。
它返回一个对数组元素的引用,允许用户读取数组中的元素,但不允许修改它们。
6-4 你好,类模板(圆的面积)
template <class T>
class Square {
private:
T width; // 正方形的边长
public:
Square(T w) { width = w; } // 构造函数
T getArea() { return width * width; } // 计算正方形的面积
};
没啥东西,经过上面的练习,相信兄弟们已经知道这个有多简单了。
源代码
6-1
#include <iostream>
using namespace std;
/* 请在这里填写答案 */
template <class T>
class MyArray
{
public:
bool check();
~MyArray();
MyArray(int);
void sort();
void display();
private:
int size;
T* data;
};
template<class T>
MyArray<T>::MyArray(int s)
{
size=s;
data=new T[size];
for(int i=0;i<size;i++)
cin>>data[i];
}
template<class T>
void MyArray<T>::display()
{
for(int i=0; i<size-1; i++) cout<<data[i]<<' ';
cout<<data[size-1]<<endl;
}
template<class T>
void MyArray<T>::sort()
{
for(int i=0; i<size; i++)
{
int min=i;
for(int j=i+1; j<size; j++)
{
if(data[min]>data[j])
{
min=j;
}
}
if(min!=i)
{
T temp=data[min];
data[min]=data[i];
data[i]=temp;
}
}
}
template<class T>
MyArray<T>::~MyArray(){ delete[] data;}
template<class T>
bool MyArray<T>::check(){
int i;
for(i=0;i<size-1;i++)
if(data[i]>data[i+1]) { cout<<"ERROR!"<<endl;return false;}
return true;
}
int main( )
{
MyArray<int> *pI;
MyArray<float> *pF;
MyArray<char> *pC;
int ty, size;
cin>>ty;
while(ty>0){
cin>>size;
switch(ty){
case 1: pI = new MyArray<int>(size); pI->sort(); pI->check(); pI->display(); delete pI; break;
case 2: pF = new MyArray<float>(size); pF->sort(); pF->check(); pF->display(); delete pF; break;
case 3: pC = new MyArray<char>(size); pC->sort(); pC->check(); pC->display(); delete pC; break;
}
cin>>ty;
}
return 0;
}
6-2
#include <iostream>
#include <string>
using namespace std;
/* 请在这里填写答案 */
template <class T>
void sort(T *arr, int size)
{
for(int i=0;i<size;i++)
{
cin>>arr[i];
}
/*
for(int i=0; i<size; i++)
{
int min=i;
for(int j=i+1; j<size; j++)
{
if(a[min]>a[j])
{
min=j;
}
}
if(min!=i)
{
T temp=a[min];
a[min]=a[i];
a[i]=temp;
}
}
*/
int j,i;
T tem;
for (i = 0; i < size-1;i ++)//size-1是因为不用与自己比较,所以比的数就少一个
{
int count = 0;
for (j = 0; j < size-1 - i; j++) //size-1-i是因为每一趟就会少一个数比较
{
if (arr[j] > arr[j+1])//这是升序排法,前一个数和后一个数比较,如果前数大则与后一个数换位置
{
tem = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tem;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
template <class T>
void display(T* a, int size){
for(int i=0; i<size-1; i++) cout<<a[i]<<' ';
cout<<a[size-1]<<endl;
}
int main() {
const int SIZE=10;
int a[SIZE];
char b[SIZE];
double c[SIZE];
string d[SIZE];
int ty, size;
cin>>ty;
while(ty>0){
cin>>size;
switch(ty){
case 1:sort(a,size); display(a,size); break;
case 2:sort(b,size); display(b,size); break;
case 3:sort(c,size); display(c,size); break;
case 4:sort(d,size); display(d,size); break;
}
cin>>ty;
}
return 0;
}
6-3
#include<bits/stdc++.h>
using namespace std;
template <class T>
class Vector
{
int tos=0; //创建一个整数用于下标表示
const int size=100; //创建一个常数用于表示动态申请空间大小
T*data; //定义一个指针,用于动态申请空间
public:
Vector() //构造函数动态申请空间
{
data=new T[size];
}
int add(int i)
{
//data=new T[size]; //不能在add函数里申请空间,因为作用域小了,add函数结束空间就被自动注销了
data[tos]=i; //存入数组
tos++;
return tos-1; //返回tos-1是根据main函数结果来的
}
int get_size()
{
return tos; //下标就代表了数组大小
}
void remove(int m)
{
for(int i=m; i<tos-1; i++) //移除某个值后后面的值需要填补上,
{
data[i]=data[i+1];
}
tos--;
}
const T& operator[](int i)//重载了[]运算符
{
return data[i];
}
};
int main() {
Vector<int> vint;
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++) {
vint.add(i);
}
cout << vint.get_size() << endl;
cout << vint[m] << endl;
vint.remove(m);
cout << vint.add(-1) << endl;
cout << vint[m] << endl;
Vector<int> vv = vint;
cout << vv[vv.get_size() - 1] << endl;
vv.add(m);
cout << vint.get_size() << endl;
return 0;
}
6-4
#include <iostream>
using namespace std;
template <class T>
class Square {
private:
T width; // 正方形的边长
public:
Square(T w) { width = w; } // 构造函数
T getArea() { return width * width; } // 计算正方形的面积
};
int main() {
int width1;
cin >> width1; // 输入正方形的边长
Square<int> square1(width1);
cout << square1.getArea() << endl; // 输出正方形的面积
double width2;
cin >> width2; // 输入正方形的边长
Square<double> square2(width2);
cout << square2.getArea() << endl; // 输出正方形的面积
return 0;
}