POJ 4093:倒排索引查询

总时间限制:
1000ms
内存限制:

131072kB

描述

现在已经对一些文档求出了倒排索引,对于一些词得出了这些词在哪些文档中出现的列表。

要求对于倒排索引实现一些简单的查询,即查询某些词同时出现,或者有些词出现有些词不出现的文档有哪些。

输入
第一行包含一个数N,1 <= N <= 100,表示倒排索引表的数目。
接下来N行,每行第一个数c i,表示这个词出现在了多少个文档中。接下来跟着c i个数,表示出现在的文档编号,编号不一定有序。1 <= c i <= 1000,文档编号为32位整数。
接下来一行包含一个数M,1 <= M <= 100,表示查询的数目。
接下来M行每行N个数,每个数表示这个词要不要出现,1表示出现,-1表示不出现,0表示无所谓。数据保证每行至少出现一个1。
输出
共M行,每行对应一个查询。输出查询到的文档编号,按照编号升序输出。
如果查不到任何文档,输出"NOT FOUND"。
样例输入
3
3 1 2 3
1 2
1 3
3
1 1 1
1 -1 0
1 -1 -1
样例输出

NOT FOUND
1 3
1

这道题就是集合的运算,对要求出现的词,即1取交集运算,对-1的词取差集运算,忽略为0的词。

#include <set>;
#include <vector>;
#include <iostream>;
#include <map>;
using namespace std;

int main()
{
	vector< set<int> > ivec;
	int N = 0;
	//输入N
	cin >> N;
	int i = 0; // N的循环变量 
	while (i < N){
		set<int> iset;
		int num = 0; 
		cin >> num;
		int j = 0;
		int docnum = 0;
		while (j < num){ // 这里输入文档编号 
			cin >> docnum;
			iset.insert(docnum);
			++j;
		}
		ivec.push_back(iset);
		++i; 
	}
	
	// 在输入要查找的数据 
 	int M = 0;
 	cin >> M; // 要查找的个数
	map<int, vector<int> > imap;
	i = 0;
	while (i < M){
		int p = 0;
		int j = 0;
		vector<int> jvec;
		while (j < N){
			cin >> p;
			jvec.push_back(p);
			++j;	
		}
		imap[i] = jvec;
		++i; 
	}
	
	// 在这里执行查找
 
	for (int x = 0; x < imap.size(); ++x){
		set<int> iresult; // 存储查找的结果
		vector<int> &xvector = imap[x];
		//先插入为1的词 
		int xx = 0;
		for (vector<int>::iterator vec_it = xvector.begin(); vec_it != xvector.end(); ++vec_it, ++xx){
			if (*vec_it == 0 || *vec_it == -1)
				continue;
			if (iresult.empty())
				iresult.insert(ivec[xx].begin(), ivec[xx].end());
			else{
				set<int> iresult2;
				for (set<int>::iterator set_it= ivec[xx].begin(); set_it != ivec[xx].end(); set_it++){
					if (iresult.find(*set_it) != iresult.end())
						iresult2.insert(*set_it);
				}
				iresult = iresult2;	
				if (iresult2.empty()){
					break;	
				}
			}
		}
		
		// 删除为-1的词 
		xx = 0;
		for (vector<int>::iterator vec_it = xvector.begin(); vec_it != xvector.end(); ++vec_it, ++xx){
			if (*vec_it == 0 || *vec_it == 1){ 
				continue;
			} 
			for (set<int>::iterator set_it= ivec[xx].begin(); set_it != ivec[xx].end(); set_it++){
				iresult.erase(*set_it);	
			}
		}
		
		if (iresult.size() < 1){
			cout << "NOT FOUND"<<endl;	
			continue;
		}		
		
		for (set<int>::iterator set_it = iresult.begin(); set_it != iresult.end(); set_it++){
			cout << *set_it << " ";
		}
		cout << endl; 
	}
	 
	
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值