最短摘要与反转链表
关于最短摘要,编程之美3.5节并没有给出详细的代码。其实还是值得一写的。下面的实现我使用了set和map来维护相关的信息。
int main() {
int n, m;
while (cin>>n>>m) {
// input
vector<string> seq;
while (n--) *back_inserter(seq) = *istream_iterator<string>(cin);
set<string> kwords;
while (m--) *inserter(kwords, kwords.end()) = *istream_iterator<string>(cin);
// find shortest abstract
typedef vector<string>::iterator Vsit;
pair<Vsit, Vsit> r(seq.begin(), seq.begin()), q = r;
set<string> notfound = kwords;
map<string, int> found;
for(;;) {
if (notfound.size()) {
if (q.second == seq.end()) break;
set<string>::iterator it = notfound.find(*q.second);
if (it != notfound.end()) {
++found[*it];
notfound.erase(it);
}
else {
map<string, int>::iterator it2 = found.find(*q.second);
if (it2 != found.end()) ++(it2->second);
}
++(q.second);
}
else {
map<string, int>::iterator it = found.find(*q.first);
if (it != found.end() && !--(it->second)) {
size_t rlen = distance(r.first, r.second);
size_t qlen = distance(q.first, q.second);
if (!rlen || rlen > qlen) r = q;
notfound.insert(it->first);
found.erase(it);
}
++(q.first);
}
}
// output
if (!distance(r.first, r.second)) cout<<"No abstract available.";
else {
if (r.first != seq.begin()) cout<<"... ";
for (bool first = true; r.first != r.second; ++r.first, first = false) {
if (!first) cout<<' ';
cout<<*r.first;
}
if (r.second != seq.end()) cout<<" ...";
}
cout<<'\n';
}
return 0;
}
顺便,把3.4节中的扩展问题单向链表反转实现也列在下面:
Node* reverse(Node* list) {
Node* prev = 0;
while (list) {
Node* t = list;
list = list->next;
t->next = prev;
prev = t;
}
return prev;
}