各大计算机公司 笔试及面试 题目 - 人民搜索(二)

 1、求包含所有query的最短距离  

一篇文章,切完词之后放到一个vector<string>中,一个查询切完词也放到一个vector<string>中,写一个函数找出这篇文章中包含这个查询中所有词的最小区间的i和j。只要返回第一个即可。


当时很坑爹,直觉告诉我要建索引,而且建索引也对了,但是建完之后就不知道怎么搞了,后台他提示一句,有些是不需要比较的,才得到灵感,想出了解决办法,但是写起代码来,又掉链子了,可能是在纸上写代码没有什么经验吧,在电脑上,我写代码还是很快了。


言归正传,建索引的思路是对的。怎么建索引呢?


对于每个query中出现的词,建立索引,当然在实际应用中,可能是对文档中出现的所有词进行建索引。所谓建索引,就是记录query中每个词在doc中出现的位置。


比如一篇文档为“a b a a c d e f a f”,query为“a e f”,那么我们建立索引为:


a: 0 2 3 8
e: 6
f:7 9


那么下边如何搞呢?


首先看索引的第一排,0 6 7,找出最大和最小为7和0,距离为7,那么0 6 9还有没有必要比较呢?答案是否定的,那当然也就有思路了,比较了0 6 7之后,0就可以删除了,下面比较2 6 7,最小为2,最大为7,距离为5,更新最小距离,继续这个过程,直到有一个索引为空为止,最终可以得到最小距离的索引。


备注:转载于http://smallbridge.sinaapp.com/124098/%E8%AF%A6%E8%A7%A3%E4%BA%BA%E6%B0%91%E6%90%9C%E7%B4%A2%E9%9D%A2%E8%AF%95%E9%A2%98-%E6%B1%82%E5%8C%85%E5%90%AB%E6%89%80%E6%9C%89query%E7%9A%84%E6%9C%80%E7%9F%AD%E8%B7%9D%E7%A6%BB.html

#include <iostream>
#include <vector>
#include <string>
#include <queue>
 
using namespace std;
 
bool find_shortest_distance(const vector<string> &doc, const vector<string> &query, int &i, int &j)
{
	// 索引的过程
	vector<queue><int> > index;
	for (vector<string>::const_iterator qit = query.begin(); qit != query.end(); qit++)
	{
		queue<int> q;
		for (vector<string>::const_iterator dit = doc.begin(); dit != doc.end(); dit++)
		{
			if (*qit == *dit)
			{
				q.push(dit - doc.begin());
			}
		}
		if (q.empty())
		{
			return false;
		}
		index.push_back(q);
	}
 
	// 求解的过程
	int min, max;
	int dis = doc.size() + 1;
 
	while (true)
	{
		min = max = index[0].front();
		vector<queue><int> >::iterator minit = index.begin();
		for (vector<queue><int> >::iterator it = index.begin(); it != index.end(); it++)
		{
			int front = it->front();
			if (front < min)
			{
				min = front;
				minit = it;
			}
			else if (front > max)
			{
				max = front;
			}
		}
		int diff = max - min;
		if (diff < dis)
		{
			dis = diff;
			i = min;
			j = max;
		}
		minit->pop();
		if (minit->empty())
		{
			break;
		}
 
	}
	return true;
}
 
int main()
{
	vector<string> doc, query;
 
	doc.push_back("a");
	doc.push_back("b");
	doc.push_back("a");
	doc.push_back("a");
	doc.push_back("c");
	doc.push_back("d");
	doc.push_back("e");
	doc.push_back("f");
	doc.push_back("a");
	doc.push_back("f");
 
	query.push_back("a");
	query.push_back("e");
	query.push_back("f");
 
	int i, j;
 
	find_shortest_distance(doc, query, i, j);
	cout << i << '\t' << j << endl;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值