今日头条2018秋招笔试题(二)合并重叠病句

问题描述:

多个编辑对一篇论文进行评审,每个编辑找出若干个病句,用[s, t]表示,s代表病句起始位置,t代表病句终止位置。不同编辑找出的病句可能有重叠,如[1,5]和[2,7],可以合并为[1,7]。要求输入每个编辑找出的病句,输出合并后的所有病句,按病句的起始位置从小到大排序输出。

问题分析:

下面的实现为每个病句做了标记(合并或未合并),而没有使用erase,减少额外开销。

代码实现:

#include 
#include 
#include 

using namespace std;

vector> sentences;		// 病句,将各编辑找出的病句放在一个vector中

bool comp(vector &a, vector &b)
{
	return a[1] < b[1];
}

void main()
{
	int M;				            // 评审数量
	cin >> M;

	// 读取病句
	for (int i = 0; i < M; i++)
	{
		vector sente(3);
		char c;
		do
		{
			sente[0] = 0;			// 辅助标记,0表示未被合并,1表示已被合并
			cin >> sente[1];		// 病句起始位置
			cin.get();				// ","
			cin >> sente[2];		// 病句终止位置
			c = cin.get();			// ";"
			sentences.push_back(sente);
		} while (c == ';');
	}

	// 合并病句
	for (int i = 0; i < sentences.size(); i++)
	{
		for (int j = i + 1; j < sentences.size(); j++)
		{
			int newS, newT;
			if ((sentences[i][2] >= sentences[j][1] && sentences[i][2] <= sentences[j][2])
				|| (sentences[j][2] >= sentences[i][1] && sentences[j][2] <= sentences[i][2]))	// 需要合并
			{
				newS = sentences[i][1] < sentences[j][1] ? sentences[i][1] : sentences[j][1];	// 新的起始
				newT = sentences[i][2] > sentences[j][2] ? sentences[i][2] : sentences[j][2];	// 新的终止
				sentences[i][0] = 1;		// 标记为已合并
				sentences[j][1] = newS;		// 合并 
				sentences[j][2] = newT;
				break;						// 跳到下一个病句
			}
		}
	}

	// 排序
	sort(sentences.begin(), sentences.end(), comp);

	// 输出
	int flag = 0;				// 标记第一个病句
	for (int i = 0; i < sentences.size(); i++)
	{
		if (!sentences[i][0])
		{
			if (flag)
				cout << ";";
			flag = 1;
			cout << sentences[i][1] << "," << sentences[i][2];
		}
	}
	cin.get();
}

 

你可能感兴趣的:(算法)