山东科技大学2020年5月25日实验题解
题目一: 自定义字符串的下标运算
Description
定义类MyString,由长度不超过100的字符串组成。重载其下标运算符:
用于重复求指定字符ch在串中的下标。
重载其输入运算符,用于输入字符串。
Input
输入一个不含空白符的字符串(长度不超过100个)和一个字符。
Output
指定字符在字符串中的所有位置。
Sample Input
babababaab a
Sample Output
1
3
5
7
8
-1
HINT
下标运算符中需要用到静态变量。
禁止使用STL,包括list、vector和string等。
题目给定代码
int main()
{
MyString mystr;
char c;
int pos;
cin>>mystr>>c;
do{
pos = mystr[c];
cout<<pos<<endl;
}while(pos != -1);
return 0;
}
标程
#include<map>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iterator>
#include<iostream>
#include<algorithm>
#define R register
#define LL long long
#define pi 3.141
#define INF 1400000000
using namespace std;
int a = 0;
class MyString{
private:
char s[101];
public:
static int n;
static int l;
friend istream& operator>>(istream& is, MyString& A){
char c;
int i = 0;
cin >> c;
while (c != ' '){
A.s[i] = c;
c = getchar();
i++;
l++;
}
A.s[i] = '\0';
return is;
}
int operator[](char c)
{
n++;
for (a = n; a < l; a++)
{
if (s[a] == c)
break;
}
n = a;
if (n == l)
return -1;
return a;
}
};
int MyString::n = 0;
int MyString::l = 0;
int main()
{
MyString mystr;
char c;
int pos;
cin >> mystr >> c;
do {
pos = mystr[c];
cout << pos << endl;
} while (pos != -1);
return 0;
}
题目二: 数组类(II)
Description
封装一个模板数组类,用于存储数组和处理的相关功能,支持以下操作:
- Array::Array(int l)构造方法:创建一个长度为l的组对象。
- Array::size()方法:返回Array对象中元素个数。
- Array::put(int n)方法:按从大到小的顺序输出前n大元素,若数组长度小于n则从大到小输出全部元素。
- 下标运算符:返回下标所指的元素。
你设计一个模板数组类Array,使得main()函数能够正确运行。
函数调用格式见append.cc。
append.cc中已给出main()函数。
Input
输入的第一个整数n,表示有n组测试数据。
后面的每行以一个整数k开头,表示后面有k个同类型的数组元素。
数组元素有以下三种类型:整数、浮点数和字符,并且按固定的次序间隔出现。
Output
把输入的数组,按值从大到小输出前10个元素,若输入不足10个则全部输出。每行数据对应一个输出。格式见sample。
Sample Input
3
10 1 2 3 4 5 6 7 8 9 0
5 1.1 2.2 3.3 4.4 5.5
20 ABCDEGHIJMNPRSTUVWXY
Sample Output
9 8 7 6 5 4 3 2 1 0
5.5 4.4 3.3 2.2 1.1
Y X W V U T S R P N
程序给定代码
int main()
{
int cases, len;
cin >> cases;
for(int ca = 1; ca <= cases; ca++)
{
cin >> len;
if(ca % 3 == 0)
{
Array<char> chr_arr(len);
for(int i = 0; i < chr_arr.size(); i++)
cin >> chr_arr[i];
chr_arr.put(10);
}
if(ca % 3 == 1)
{
Array<int> int_arr(len);
for(int i = 0; i < int_arr.size(); i++)
cin >> int_arr[i];
int_arr.put(10);
}
if(ca % 3 == 2)
{
Array<double> dbl_arr(len);
for(int i = 0; i < dbl_arr.size(); i++)
cin >> dbl_arr[i];
dbl_arr.put(10);
}
}
}
标程
#include<map>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iterator>
#include<iostream>
#include<algorithm>
#define R register
#define LL long long
#define pi 3.141
#define INF 1400000000
using namespace std;
template <class T>
class Array {
private:
T* number;
int length;
public:
Array(int l) {
number = new T[l + 1], length = l;
}
void put(int n) {
for (R int i = 0; i < length - 1; ++i) {
for (R int j = i + 1; j < length; ++j) {
if (number[j] > number[i]) {
T temp = number[j];
number[j] = number[i], number[i] = temp;
}
}
}
if (n > length) {
for (R int i = 0; i < length - 1; ++i) {
cout << number[i] << " ";
}
cout << number[length - 1] << "\n";
}
else {
for (R int i = 0; i < n - 1; ++i) {
cout << number[i] << " ";
}
cout << number[n - 1] << "\n";
}
}
int size() {
return length;
}
T& operator[](int n) {
return number[n];
}
friend istream& operator >> (istream& is, Array& N) {
T a;
is >> a;
return is;
}
~Array() {
delete[]number;
}
};
int main()
{
int cases, len;
cin >> cases;
for (int ca = 1; ca <= cases; ca++)
{
cin >> len;
if (ca % 3 == 0)
{
Array<char> chr_arr(len);
for (int i = 0; i < chr_arr.size(); i++)
cin >> chr_arr[i];
chr_arr.put(10);
}
if (ca % 3 == 1)
{
Array<int> int_arr(len);
for (int i = 0; i < int_arr.size(); i++)
cin >> int_arr[i];
int_arr.put(10);
}
if (ca % 3 == 2)
{
Array<double> dbl_arr(len);
for (int i = 0; i < dbl_arr.size(); i++)
cin >> dbl_arr[i];
dbl_arr.put(10);
}
}
}
题目三: 数量的类模板
Description
定义一个类模板Data,用于包装C++中的基本数据类型int和double。它包括:
-
数据成员value为该对象所包装的值。
-
无参构造函数(初始化value为0)和带参构造函数。
-
重载的运算符:>、<、+以及<<。其中"+"返回和,不改变两个操作数的值。
-
成员函数setValue用于设置value的值。
定义另一个类模板GetResult,它只有3个静态成员函数(以下“T"为类型参数):
-
static Data getSum(Data *arr, int num):求存储在arr中的num个Data对象的和,并返回由这个和构成的一个Data对象。
-
static Data getMax(Data *arr, int num):求存储在arr中的num个Data对象的最大值,并返回这个最大值对应的对象。
-
static Data getMin(Data *arr, int num):求存储在arr中的num个Data对象的最小值,并返回这个最小值对应的对象。
Input
输入分多行。
第一行M>0表示有M个测试用例。
只有的M行,每行开始有一个字母i或d,第二个是正整数N>0。如果第一个字母是i,则表示本行包括N个int类型的数据;如果第一个字母为d,则表示本行有N个double类型的数据。
Output
除前6行输出外,其他输出的行数等于M。其中每一行输出3个数据:对应测试用例的最大值、最小值以及和。实数输出定点小数,且只输出2位小数。
Sample Input
3
i 3 1 2 3
d 3 1.1 2.2 3.3
i 1 10
Sample Output
a + b = 30
max(a, b) = 20
min(a, b) = 10
c + d = -0.96
max(c, d) = 3.14
min(c, d) = -4.10
3 1 6
3.30 1.10 6.60
10 10 10
题目给定代码
int main()
{
Data<int> iData[1001];
Data<double> dData[1001];
int cases, num;
char ch;
int u;
double v;
Data<int> a(10), b(20);
Data<double> c(3.14), d(-4.1);
cout<<"a + b = "<<(a + b)<<endl;
cout<<"max(a, b) = "<<(a > b ? a : b)<<endl;
cout<<"min(a, b) = "<<(a < b ? a : b)<<endl;
cout<<"c + d = "<<(c + d)<<endl;
cout<<"max(c, d) = "<<(c > d ? c : d)<<endl;
cout<<"min(c, d) = "<<(c < d ? c : d)<<endl;
cin>>cases;
for (int i = 0; i < cases; i++)
{
cin>>ch;
cin>>num;
for (int j = 0; j < num; j++)
{
if (ch == 'i')
{
cin>>u;
iData[j].setValue(u);
}
else if (ch == 'd')
{
cin>>v;
dData[j].setValue(v);
}
}
if (ch == 'i')
{
cout<<GetResult<int>::getMax(iData, num);
cout<<" "<<GetResult<int>::getMin(iData, num);
cout<<" "<<GetResult<int>::getSum(iData, num)<<endl;
}
else if (ch == 'd')
{
cout<<GetResult<double>::getMax(dData, num);
cout<<" "<<GetResult<double>::getMin(dData, num);
cout<<" "<<GetResult<double>::getSum(dData, num)<<endl;
}
}
return 0;
}
标程
#include<map>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iterator>
#include<iostream>
#include<algorithm>
#define R register
#define LL long long
#define pi 3.141
#define INF 1400000000
using namespace std;
template <class T>
class Data {
private:
T value;
public:
void setValue(T v) {
value = v;
}
T operator + (Data <T> data) {
return value + data.value;
}
bool operator > (Data <T> data) {
if (value > data.value) {
return 1;
}
return 0;
}
bool operator < (Data <T> data) {
if (value < data.value) {
return 1;
}
return 0;
}
friend ostream& operator << (ostream& os, Data <T> data) {
os << fixed << setprecision(2) << data.value;
return os;
}
Data(T v = 0) {
value = v;
}
};
template <class T>
class GetResult {
public:
static Data<T> getSum(Data<T>* arr, int num) {
Data<T> sum(arr[0]);
for (R int i = 1; i < num; ++i) {
sum = arr[i] + sum;
}
return sum;
}
static Data<T> getMax(Data<T>* arr, int num) {
Data<T> max(arr[0]);
for (R int i = 1; i < num; ++i) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
static Data<T> getMin(Data<T>* arr, int num) {
Data<T> min(arr[0]);
for (R int i = 1; i < num; ++i) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
};
int main()
{
Data<int> iData[1001];
Data<double> dData[1001];
int cases, num;
char ch;
int u;
double v;
Data<int> a(10), b(20);
Data<double> c(3.14), d(-4.1);
cout << "a + b = " << (a + b) << endl;
cout << "max(a, b) = " << (a > b ? a : b) << endl;
cout << "min(a, b) = " << (a < b ? a : b) << endl;
cout << "c + d = " << (c + d) << endl;
cout << "max(c, d) = " << (c > d ? c : d) << endl;
cout << "min(c, d) = " << (c < d ? c : d) << endl;
cin >> cases;
for (int i = 0; i < cases; i++)
{
cin >> ch;
cin >> num;
for (int j = 0; j < num; j++)
{
if (ch == 'i')
{
cin >> u;
iData[j].setValue(u);
}
else if (ch == 'd')
{
cin >> v;
dData[j].setValue(v);
}
}
if (ch == 'i')
{
cout << GetResult<int>::getMax(iData, num);
cout << " " << GetResult<int>::getMin(iData, num);
cout << " " << GetResult<int>::getSum(iData, num) << endl;
}
else if (ch == 'd')
{
cout << GetResult<double>::getMax(dData, num);
cout << " " << GetResult<double>::getMin(dData, num);
cout << " " << GetResult<double>::getSum(dData, num) << endl;
}
}
return 0;
}
题目四: 模板是个好东西
Description
定义Point类:
-
有两个int类型的数据成员,表示其横纵坐标。
-
无参构造函数,初始化两个坐标为0。
-
带参构造函数。
-
重载其输出运算符<<,用于输出一个点的横坐标和纵坐标,中间用一个空格隔开。
定义一个类模板Data:
-
只有一个数据成员data,data的类型是由类型参数指定的。
-
定义该类模板的构造函数。
-
定义void show()方法,用于显示data的值。
Input
输入有5行。
第1行是一个不含空白符的字符串。
第2~4行分别是一个整数,其中第2、3行是点的坐标值。
最后一行是一个字符。
Output
见样例。
Sample Input
test
1
2
3
c
Sample Output
c
3
test
1 2
题目给定代码
int main()
{
string n;
int x, y, d;
char c;
cin>>n;
cin>>x>>y>>d;
cin>>c;
Point p(x, y);
Data<char> aChar(c);
Data<int> anInt(d);
Data<Point> aPoint(p);
Data<string> aString(n);
aChar.show();
anInt.show();
aString.show();
aPoint.show();
return 0;
}
标程
#include<map>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iterator>
#include<iostream>
#include<algorithm>
#define R register
#define LL long long
#define pi 3.141
#define INF 1400000000
using namespace std;
class Point {
private:
int x, y;
public:
Point(int x_x = 0, int y_y = 0) {
x = x_x, y = y_y;
}
friend ostream& operator << (ostream& os, const Point point) {
os << point.x << " " << point.y << "\n";
return os;
}
};
template <class T>
class Data {
private:
T data;
public:
Data(T d = 0) {
data = d;
}
void show() {
cout << data << "\n";
}
};
int main()
{
string n;
int x, y, d;
char c;
cin >> n;
cin >> x >> y >> d;
cin >> c;
Point p(x, y);
Data<char> aChar(c);
Data<int> anInt(d);
Data<Point> aPoint(p);
Data<string> aString(n);
aChar.show();
anInt.show();
aString.show();
aPoint.show();
return 0;
}
题目五: 字符串类(II)
Description
封装一个字符串类,用于存储字符串和处理的相关功能,支持以下操作:
-
STR::STR()构造方法:创建一个空的字符串对象。
-
STR::STR(const char *)构造方法:创建一个字符串对象,串的内容由参数给出。
-
STR::length()方法:返回字符串的长度。
-
STR::putline()方法:输出串的内容,并换行。
-
运算符“+”和“+=”,表示两个字符串的连接运算,规则为:
c = a + b 表示串c中的字符是a和b的连接:“a+b”的结果是一个新的字符串,串a和串b的内容不变。
a += b 表示串a中的字符是a和b的连接:串b中的内容不变
你设计一个字符串类STR,使得main()函数能够正确运行。
函数调用格式见append.cc。
append.cc中已给出main()函数。
Invalid Word(禁用单词)错误:“string”、“vector”等被禁用。
Input
输入有若干行,每行一个字符串。
Output
每组测试数据对应输出一行,包含两部分内容,首先是一个整数,表示输入串的长度,然后是输入的字符串,两者用一个空格分开。格式见sample。
Sample Input
A
123456789
Sample Output
12 Hello World!
0
12 Hello World!
12 Hello World!
12 Hello World!
10 A123456789
1 A
9 123456789
10 123456789A
1 A
题目给定代码
int main()
{
STR e;
STR h("Hello World!");
STR he = e + h;
cout << he.length() << " ";
he.putline();
cout << e.length() << " ";
e.putline();
cout << h.length() << " ";
h.putline();
e += h;
cout << e.length() << " ";
e.putline();
cout << h.length() << " ";
h.putline();
char s1[100001], s2[100001];
while (gets(s1) != NULL && gets(s2) != NULL)
{
STR str1(s1), str2(s2);
STR str = str1 + str2;
cout << str.length() << " ";
str.putline();
cout << str1.length() << " ";
str1.putline();
cout << str2.length() << " ";
str2.putline();
str2 += str1;
cout << str2.length() << " ";
str2.putline();
cout << str1.length() << " ";
str1.putline();
}
}
标程
#include <bits/stdc++.h>
using namespace std;
class STR {
private:
char* a;
public:
STR() :a(NULL) {}
STR(const char* s) {
int len = strlen(s);
a = new char[len + 10];
strcpy(a, s);
}
~STR() { delete[] a; }
STR(const STR& s) {
a = new char[s.length() + 10];
strcpy(a, s.a);
}
int length() const {
if (a != NULL) {
return strlen(a);
}
return 0;
}
void putline() const {
if (a != NULL) {
cout << a;
}
cout << endl;
}
STR operator+(STR& s1) {
STR s;
if (a != NULL) {
int len = strlen(s1.a) + strlen(a);
s.a = new char[len + 10];
strcpy(s.a, a);
strcat(s.a, s1.a);
return s;
}
return s1;
}
STR& operator+= (STR& ss) {
if (a != NULL) {
STR s1;
int len = strlen(a);
s1.a = new char[len + 10];
strcpy(s1.a, a);
delete[] a;
len += ss.length();
a = new char[len + 10];
strcpy(a, s1.a);
strcat(a, ss.a);
return *this;
}
a = new char[ss.length() + 10];
strcpy(a, ss.a);
return *this;
}
};
int main()
{
STR e;
STR h("Hello World!");
STR he = e + h;
cout << he.length() << " ";
he.putline();
cout << e.length() << " ";
e.putline();
cout << h.length() << " ";
h.putline();
e += h;
cout << e.length() << " ";
e.putline();
cout << h.length() << " ";
h.putline();
char s1[100001], s2[100001];
while (gets(s1) != NULL && gets(s2) != NULL)
{
STR str1(s1), str2(s2);
STR str = str1 + str2;
cout << str.length() << " ";
str.putline();
cout << str1.length() << " ";
str1.putline();
cout << str2.length() << " ";
str2.putline();
str2 += str1;
cout << str2.length() << " ";
str2.putline();
cout << str1.length() << " ";
str1.putline();
}
}