C++ STL list vector 007: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

解题
用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;
      
      }
    }
}
发布了77 篇原创文章 · 获赞 3 · 访问量 3045

猜你喜欢

转载自blog.csdn.net/BLUEsang/article/details/105211544
今日推荐