问题描述:
多个编辑对一篇论文进行评审,每个编辑找出若干个病句,用[s, t]表示,s代表病句起始位置,t代表病句终止位置。不同编辑找出的病句可能有重叠,如[1,5]和[2,7],可以合并为[1,7]。要求输入每个编辑找出的病句,输出合并后的所有病句,按病句的起始位置从小到大排序输出。
问题分析:
下面的实现为每个病句做了标记(合并或未合并),而没有使用erase,减少额外开销。
代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> sentences; // 病句,将各编辑找出的病句放在一个vector中
bool comp(vector<int> &a, vector<int> &b)
{
return a[1] < b[1];
}
void main()
{
int M; // 评审数量
cin >> M;
// 读取病句
for (int i = 0; i < M; i++)
{
vector<int> 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();
}