描述
写一个程序完成以下命令:
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
解题
用vector存放——超时方法
定义vector数组,20000个
vector<int> v[20010];
new
输入后直接略过;
if (s=="new"){
cin>>n1;
}
add
放入对应的vector中;
if(s=="add"){
cin>>n1>>n2;
v[n1].push_back(n2);
}
merge
n2的内容挨个pushback至n1,然后排序n1,清空n2;这个时间复杂度有点高,直接超时;
if(s=="merge"){
cin>>n1>>n2;
vector<int>::iterator i;
for(i=v[n2].begin();i<v[n2].end();i++)
v[n1].push_back(*i);
sort(v[n1].begin(),v[n1].end());
v[n2].clear();
}
out
定义迭代器,挨个输出;
if(s=="out"){
cin>>n1;
vector<int>::iterator i;
for (i=v[n1].begin();i<v[n1].end();i++){
cout<<*i<<" ";
}
cout<<endl;
}
unique
先排序,后unique
unique是把无重复的元素放在vector前排,迭代器指向无重复的元素的后一个。
故需要erase迭代器以及后面的元素。
if(s=="unique"){ //先排序,再unique
cin>>n1;
sort(v[n1].begin(),v[n1].end());
vector<int>::iterator new_end = unique(v[n1].begin(),v[n1].end());//"删除"相邻的重复元素
v[n1].erase(new_end, v[n1].end());//删除(真正的删除)重复的元素
/*注:unique函数功能是去除相邻的重复元素,注意是相邻,
所以必须先使用sort函数。还有一个容易忽视的特性是它并不真正把重复的元素删除。
之所以说比不真正把重复的元素删除,因为unique实际上并没有删除任何元素,
而是将无重复的元素复制到序列的前段,从而覆盖相邻的重复元素。
unique返回的迭代器指向超出无重复的元素范围末端的下一个位置。
*/
}
完整代码
#include<iostream>
#include <vector>
#include <cstring>
#include <list>
#include <algorithm>
using namespace std;
int main(){
int num;
string s;
int n1;
int n2;
vector<int> v[20000];
cin>>num;
while(num--){
cin>>s;
if (s=="new"){
cin>>n1;
}
if(s=="add"){
cin>>n1>>n2;
v[n1].push_back(n2);
}
if(s=="merge"){
cin>>n1>>n2;
vector<int>::iterator i;
for(i=v[n2].begin();i<v[n2].end();i++)
v[n1].push_back(*i);
sort(v[n1].begin(),v[n1].end());
v[n2].clear();
}
if(s=="out"){
cin>>n1;
vector<int>::iterator i;
for (i=v[n1].begin();i<v[n1].end();i++){
cout<<*i<<" ";
}
cout<<endl;
}
if(s=="unique"){ //先排序,再unique
cin>>n1;
sort(v[n1].begin(),v[n1].end());
vector<int>::iterator new_end = unique(v[n1].begin(),v[n1].end());//"删除"相邻的重复元素
v[n1].erase(new_end, v[n1].end());//删除(真正的删除)重复的元素
/*注:unique函数功能是去除相邻的重复元素,注意是相邻,
所以必须先使用sort函数。还有一个容易忽视的特性是它并不真正把重复的元素删除。
之所以说比不真正把重复的元素删除,因为unique实际上并没有删除任何元素,
而是将无重复的元素复制到序列的前段,从而覆盖相邻的重复元素。
unique返回的迭代器指向超出无重复的元素范围末端的下一个位置。
*/
}
}
}
标准答案——用List存放
lists列表存放list成员
list<int> lists[20000];
switch case的方法
add
case 'a': //add
scanf("%d%d",&id1,&num);
lists[id1].push_back(num);
break;
new
case 'n': //new
scanf("%d",&id1);
break;
merge
case 'm': //merge
scanf("%d%d",&id1,&id2);
lists[id1].merge (lists[id2]);
break;
unique
case 'u': //unique
scanf("%d",&id1);
lists[id1].sort(); //先排序
lists[id1].unique (); //后unique
break;
out
case 'o': //out
scanf("%d",&id1);
lists[id1].sort(); //先排序
for( li = lists[id1].begin(); li != lists[id1].end(); li ++)
printf("%d ",*li); //利用迭代器挨个输出
printf("\n");
break;
完整代码
#include <list>
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
list<int> lists[20000];
int n;
scanf("%d",&n);
char cmd[20];
int id1,id2,num;
list<int>::iterator li; //迭代器 li
while( n -- ) {
scanf("%s",cmd);
switch(cmd[0]) {
case 'a': //add
scanf("%d%d",&id1,&num);
lists[id1].push_back(num);
break;
case 'n': //new
scanf("%d",&id1);
break;
case 'm': //merge
scanf("%d%d",&id1,&id2);
lists[id1].merge (lists[id2]);
break;
case 'u': //unique
scanf("%d",&id1);
lists[id1].sort();
lists[id1].unique ();
break;
case 'o': //out
scanf("%d",&id1);
lists[id1].sort();
for( li = lists[id1].begin(); li != lists[id1].end(); li ++)
printf("%d ",*li);
printf("\n");
break;
}
}
}