一、Week8_01 Goodcopy
输入
第一行是整数 t,表示数据组数
每组数据:
第一行是整数 n , n < 50
第二行是 n 个整数
第三行是 n 个字符串
输出
将输入的整数原序输出两次,用","分隔
然后将输入的字符串原序输出两次,也用 ","分隔
样例输入
2
4
1 2 3 4
Tom Jack Marry Peking
1
0
Ted
样例输出
1,2,3,4,
1,2,3,4,
Tom,Jack,Marry,Peking,
Tom,Jack,Marry,Peking,
0,
0,
Ted,
Ted,
#include "stdafx.h"
#include<string>
#include <iostream>
using namespace std;
template <class T>
struct GoodCopy {
// 在此处补充你的代码
void operator () (T * begin,T * end,T * x) {
bool backward = false;
T * temp;
for (temp=begin; temp != end; ++temp)
{
if (temp==x)
{
backward = true;
break;
}
}
if (backward)//需要倒着赋值,才不会覆盖掉需要的值
{
T * s = begin;//为了不更改begin和end的的指向。
T * e = end;
for (temp = x; s != end; ++temp, ++s);// 把temp移动到 x+m处
for (T* i = end; i != begin; --temp, --i)
{
*temp = *i;
}
*temp = *begin;//当i==begin时,循环结束。但是x处却没有赋值。所以还需赋值一次。
}
else
{
for (; begin != end; ++begin, ++x)
{
*x = *begin;
}
}
}
// 在此处补充你的代码
};
int a[200];
int b[200];
string c[200];
string d[200];
template <class T>
void Print(T s, T e) {
for (; s != e; ++s)
cout << *s << ",";
cout << endl;
}
int main()
{
int t;
cin >> t; //组数
while (t--) { //每组元素个数
int m;
cin >> m;
for (int i = 0; i < m; ++i)
cin >> a[i];
GoodCopy<int>()(a, a + m, b); //将a ~ a+m的元素复制到b中。
Print(b, b + m);
GoodCopy<int>()(a, a + m, a + m / 2);
Print(a + m / 2, a + m / 2 + m);
for (int i = 0; i < m; ++i)
cin >> c[i];
GoodCopy<string>()(c, c + m, d);
Print(c, c + m);
GoodCopy<string>()(c, c + m, c + m / 2);
Print(c + m / 2, c + m / 2 + m);
}
return 0;
}
二、Week8_02 按距离排序
输入
多组数据,每组一行,是一个整数n和一个字符串s
输出
定义两个整数的距离为两个整数差的绝对值
定义两个字符串的距离为两个字符串长度差的绝对值
对每组数据:
对数组a按和n的距离从小到大排序后输出。距离相同的,值小的排在前面。
然后对数组b,按照和s的距离从小到大输出。距离相同的,字典序小的排在前面
样例输入
2 a123456
4 a12345
样例输出
1,3,0,4,7,8,9,10,15,20,
American,Peking,123456789,Jack,To,abcdefghijklmnop,
4,3,1,7,0,8,9,10,15,20,
Peking,American,Jack,123456789,To,abcdefghijklmnop,
#include "stdafx.h"
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
template <class T1, class T2>
struct Closer {
// 在此处补充你的代码
T1 v;
T2 dis;
Closer(T1 n, T2 d) :v(n), dis(d) { }
bool operator() (const T1 & v1, const T1 & v2) { // 送入比较器里的是容器内的元素
int d1 = dis(v1, v);
int d2 = dis(v2, v);
if (d1 < d2)
return true;
else if (d1 > d2)
return false;
else
return v1 < v2; // 按字典序排序 or 按值排序
//string 类 可以使用 < 进行比较的。
}
// 在此处补充你的代码
};
int Distance1(int n1, int n2) {
return abs(n1 - n2);//包含头文件 math.c (cmath)
}
int Distance2(const string & s1, const string & s2)
{
return abs((int)s1.length() - (int)s2.length());
}
int a[10] = { 0,3,1,4,7,9,20,8,10,15 };
string b[6] = { "American","Jack","To","Peking","abcdefghijklmnop","123456789" };
int main()
{
int n; string s;
while (cin >> n >> s) {
sort(a, a + 10, Closer<int, int(*)(int, int) > (n, Distance1)); //sort 用于比较的是元素,而不是迭代器
for (int i = 0; i < 10; ++i)
cout << a[i] << ",";
cout << endl;
sort(b, b + 6, Closer<string, int(*)(const string &, const string &)>(s, Distance2));
for (int i = 0; i < 6; ++i)
cout << b[i] << ",";
cout << endl;
}
return 0;
}
三、Week8_03 很难蒙混过关的CArray3d三维数组模板类
输入
无
输出
等同于样例
样例输入
无
样例输出
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
20,21,22,23,24,
25,26,27,28,29,
30,31,32,33,34,
35,36,37,38,39,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
0,0,0,0,0,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
10,5,
5,3.33333,
layer 1:
5,3.33333,
3.33333,2.5,
layer 2:
3.33333,2.5,
2.5,2,
7,3.33333
提示
建议做法:
- a[i][j][k] 这个表达式的第一个[]返回一个内部类的对象,该内部类也重载了[],且返回值为指针。
- 必要时需重载对象到指针的强制类型转换运算符
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
template <class T>
class CArray3D
{
// 在此处补充你的代码
public:
int L, r, c; //数组共L层,每层r行,每行c列
T * p;
class Aid {
public:
T * lp; // lp是某一层的元素的起始地址
int c; //数组共L层,每层r行,每行c列
Aid(T * p_, int c_):lp(p_), c(c_) { }
T * operator [](int r) {
return lp + r*c; //返回值就是本层的第 r行的元素的起始地址
}
operator T *() { //类型强制转换运算符重载,CArray -> 指针型;
return lp;
}
};
CArray3D (int l_, int r_, int c_) :L(l_), r(r_), c(c_) {
p = new T[L * r * c];
}
Aid operator [](int L) { //返回的对象里的p记录了第L层元素的起始地址
T * lp = p + L * r * c;
return Aid(lp, c);
}
~CArray3D() { delete[] p; }
// 在此处补充你的代码
};
CArray3D<int> a(3, 4, 5);
CArray3D<double> b(3, 2, 2);
void PrintA()
{
for (int i = 0; i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for (int j = 0; j < 4; ++j) {
for (int k = 0; k < 5; ++k)
cout << a[i][j][k] << ",";
cout << endl;
}
}
}
void PrintB()
{
for (int i = 0; i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for (int j = 0; j < 2; ++j) {
for (int k = 0; k < 2; ++k)
cout << b[i][j][k] << ",";
cout << endl;
}
}
}
int main()
{
int No = 0;
for (int i = 0; i < 3; ++i) {
a[i];
for (int j = 0; j < 4; ++j) {
a[j][i];
for (int k = 0; k < 5; ++k)
a[i][j][k] = No++;
a[j][i][i];
}
}
PrintA();
memset(a[1], -1, 20 * sizeof(int));//数组赋值,将-1 连续赋给a[1]
memset(a[1], -1, 20 * sizeof(int));
PrintA();
memset(a[1][1], 0, 5 * sizeof(int));
PrintA();
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 2; ++j)
for (int k = 0; k < 2; ++k)
b[i][j][k] = 10.0 / (i + j + k + 1);
PrintB();
int n = a[0][1][2];
double f = b[0][1][1];
cout << "****" << endl;
cout << n << "," << f << endl;
return 0;
}
四、Week8_04 函数对象的过滤器
输入
多组数据
每组数据两行
第一行是两个整数 m 和 n
第二行先是一个整数k ,然后后面跟着k个整数
输出
对每组数据,按原顺序输出第二行的后k个整数中,大于m且小于n的数
输出两遍
数据保证一定能找到符合要求的整数
样例输入
1 3
1 2
2 8
5 1 2 3 4 9
样例输出
2,
2,
3,4,
3,4,
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
struct A {
int v;
A() { }
A(int n) :v(n) { };
bool operator<(const A & a) const {
return v < a.v;
}
};
// 在此处补充你的代码
template <class T>
class FilterClass { //类名后无括号
public:
T a, b;
FilterClass(T a_, T b_):a(a_),b(b_) { }
bool operator ()(T x) {
if ((x < b)&& ( a < x))
return true;
else
return false;
}
};
// 在此处补充你的代码
template <class T>
void Print(T s, T e)
{
for (; s != e; ++s)
cout << *s << ",";
cout << endl;
}
template <class T1, class T2, class T3>
T2 Filter(T1 s, T1 e, T2 s2, T3 op)
{
for (; s != e; ++s) {
if (op(*s)) {
*s2 = *s;
++s2;
}
}
return s2;
}
ostream & operator <<(ostream & o, A & a)
{
o << a.v;
return o;
}
vector<int> ia;
vector<A> aa;
int main()
{
int m, n;
while (cin >> m >> n) {
ia.clear();
aa.clear();
int k, tmp;
cin >> k;
for (int i = 0; i < k; ++i) {
cin >> tmp;
ia.push_back(tmp);
aa.push_back(tmp);
}
vector<int> ib(k);
vector<A> ab(k);
vector<int>::iterator p = Filter(ia.begin(), ia.end(), ib.begin(), FilterClass<int>(m, n));
Print(ib.begin(), p);
vector<A>::iterator pp = Filter(aa.begin(), aa.end(), ab.begin(), FilterClass<A>(m, n));
Print(ab.begin(), pp);
}
return 0;
}
五、Week8_05 白给的list排序
输入
无
输出
9.8,7.3,3.4,2.6,1.2,
样例输入
无
样例输出
同输入
#include "stdafx.h"
//#include <cstdio>
#include <iostream>
#include<functional>
#include <algorithm> //包含 sort
#include <list>
using namespace std;
int main()
{
double a[] = { 1.2,3.4,9.8,7.3,2.6 };
list<double> lst(a, a + 5);
lst.sort(
// 在此处补充你的代码
greater<double>() //在visual stdio 里会报错,显示greater 未定义(需要包含头文件<functional>,dev 里则不用包含。
// 在此处补充你的代码
);
for (list<double>::iterator i = lst.begin(); i != lst.end(); ++i)
cout << *i << ",";
return 0;
}
六、Week8_06 我自己的 ostream_iterator
输入
无
输出
5,21,14,2,3,
1.4–5.56–3.2–98.3–3.3–
样例输入
无
样例输出
同输入
#include "stdafx.h"
#include <iostream>
#include <list>
#include <string>
using namespace std;
template <class T1, class T2>
void Copy(T1 s, T1 e, T2 x) //复制函数
{
for (; s != e; ++s, ++x)
*x = *s;
}
template<class T>
class myostream_iteraotr
{
// 在此处补充你的代码
private:
string sep;// 分隔符
ostream & os;
public:
myostream_iteraotr (ostream & o,string s):os(o),sep(s){ }
void operator ++(){}
myostream_iteraotr & operator *()
{
return *this;//返回它本身,以便接下来调用 重载的()函数 进行输出
}
myostream_iteraotr & operator =(const T & val) {
os << val << sep;
return *this; //这里返回对象本身,是为了保持输出的连贯,使得(a=b)=c 成立;
}
//void operator =(const T & val) {
// os << val << sep;
// return *this;
//}
// 在此处补充你的代码
};
int main()
{
const int SIZE = 5;
int a[SIZE] = { 5,21,14,2,3 };
double b[SIZE] = { 1.4, 5.56,3.2,98.3,3.3 };
list<int> lst(a, a + SIZE);
myostream_iteraotr<int> output(cout, ",");
Copy(lst.begin(), lst.end(), output);
cout << endl;
myostream_iteraotr<double> output2(cout, "--");
Copy(b, b + SIZE, output2);
return 0;
}
七、Week8_07 List描述
写一个程序完成以下命令:
new id ——新建一个指定编号为id的序列(id<10000)
add id num——向编号为id的序列加入整数num
merge id1 id2——合并序列id1和id2中的数,并将id2清空
unique id——去掉序列id中重复的元素
out id ——从小到大输出编号为id的序列中的元素,以空格隔开
输入
第一行一个数n,表示有多少个命令( n<=200000)。以后n行每行一个命令。
输出
按题目要求输出。
样例输入
16
new 1
new 2
add 1 1
add 1 2
add 1 3
add 2 1
add 2 2
add 2 3
add 2 4
out 1
out 2
merge 1 2
out 1
out 2
unique 1
out 1
样例输出
1 2 3
1 2 3 4
1 1 2 2 3 3 4
1 2 3 4
#include "stdafx.h"
#include<list>
#include<string>
#include<iterator>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
list<int>Aid[100];
int n;
int id=0, num;
string cmd;
cin >> n;
while (n --)
{
cin >> cmd;
if (cmd=="new")
{
cin >> id;
}
else if (cmd=="add")
{
cin >>id>> num;
Aid[id].push_back(num);
}
else if (cmd=="out")
{
cin >> id;
list<int>::iterator i; //迭代器初始化时并不用指明那个容器。
for (i= Aid[id].begin(); i != Aid[id].end(); ++i) //这个begin和end 后都需要加上().
{
cout << *i<<" ";
}
}
else if (cmd == "unique") {
cin >> id;
Aid[id].sort(); // By Guo Wei,关键是先sort后unique.
Aid[id].unique();
}
else if(cmd =="merge")
{
int id1, id2;
cin >> id1 >> id2;
Aid[id1].merge(Aid[id2]);
}
}
/*while (n--) {
scanf("%s", cmd);
switch (cmd[0]) { //因为string 类不能使用switch,所以转化成char 使用switch
case 'a':
scanf("%d%d", &id1, &num);
lists[id1].push_back(num);
break;
case 'n':
scanf("%d", &id1);
break;
case 'm':
scanf("%d%d", &id1, &id2);
lists[id1].merge(lists[id2]);
break;
case 'u':
scanf("%d", &id1);
lists[id1].sort();
lists[id1].unique();
break;
case 'o':
scanf("%d", &id1);
lists[id1].sort();
for (li = lists[id1].begin(); li != lists[id1].end(); li++)
printf("%d ", *li);
printf("\n");
break;
}
}*/
return 0;
}