在Accelerated C++中,找每个单词对应的行数,有如下函数:
// ex7.3--xref函数实现
// 时间:2013-1-2 22:01:56
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include "split.h"
using std::istream;
using std::vector;
using std::string;
using std::map;
// 查找指向输入中每一个单词的所有行
map<string, vector<int> > xref(istream& in, vector<string> find_words(const string&) = split)
{
string line;
int line_number = 0;
map<string, vector<int> > ret;
// 读取下一行
while (getline(in, line))
{
++line_number; // 行号加1
// 把输入行的分割成单词
vector<string> words = find_words(line);
// 记住出现在当前行中的每一个单词
for (vector<string>::const_iterator it = words.begin();
it != words.end(); ++it)
{
ret[*it].push_back(line_number);
}
}
return ret;
}
这有一个问题,就是当一个单词在同行上出现多次使,那么map里面的vector<int>就会记录多次,那么如何让程序检测多次出现在相同行单词只记录一次呢?
下面是这个程序才改进:可以用两种不同的方法,但显然,方法1的效率要高于方法2的:
方法1:
// 查找指向输入中每一个单词的所有行
map<string, vector<int> > xref(istream& in, vector<string> find_words(const string&) = split)
{
string line;
int line_number = 0;
map<string, vector<int> > ret;
// 读取下一行
while (getline(in, line))
{
++line_number; // 行号加1
// 把输入行的分割成单词
vector<string> words = find_words(line);
// 记住出现在当前行中的每一个单词
for (vector<string>::const_iterator it = words.begin();
it != words.end(); ++it)
{
vector<string>::const_iterator it1 = words.begin();
for (; it1 != it; ++it1)
{ // 如果当前行有两个单词相同
if (*it1 == *it)
{
break;
}
}
if (it1 == it)
{ // 如果*it和它前面的单词都不同
ret[*it].push_back(line_number);
}
}
}
return ret;
}
方法2:
// 查找指向输入中每一个单词的所有行
map<string, vector<int> > xref(istream& in, vector<string> find_words(const string&) = split)
{
string line;
int line_number = 0;
map<string, vector<int> > ret;
// 读取下一行
while (getline(in, line))
{
++line_number; // 行号加1
// 把输入行的分割成单词
vector<string> words = find_words(line);
// 记住出现在当前行中的每一个单词
for (vector<string>::const_iterator it = words.begin();
it != words.end(); ++it)
{
int flag = 0; // 标识同一行是否有相同单词
vector<string>::const_iterator it1 = words.begin();
for (; it1 != it; ++it1)
{ // 如果当前行有两个单词相同
if (*it1 == *it)
{
++flag;
}
}
if (0 == flag)
{ // 如果*it和它前面的单词都不同
ret[*it].push_back(line_number);
}
}
}
return ret;
}