146 lines
3.8 KiB
C++
146 lines
3.8 KiB
C++
#include <map>
|
||
#include <iostream>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
#include "split.h"
|
||
|
||
using std::cin; using std::cout;
|
||
using std::endl; using std::getline;
|
||
using std::istream; using std::string;
|
||
using std::vector; using std::map;
|
||
|
||
// find all the lines that refer to each word in the input
|
||
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;
|
||
|
||
// read the next line
|
||
while (getline(in, line)) {
|
||
++line_number;
|
||
|
||
// break the input line into words
|
||
vector<string> words = find_words(line);
|
||
|
||
// remember that each word occurs on the current line
|
||
#ifdef _MSC_VER
|
||
for (std::vector<string>::const_iterator it = words.begin();
|
||
#else
|
||
for (vector<string>::const_iterator it = words.begin();
|
||
#endif
|
||
it != words.end(); ++it)
|
||
ret[*it].push_back(line_number);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int main()
|
||
{
|
||
// call `xref' using `split' by default
|
||
map<string, vector<int> > ret = xref(cin);
|
||
|
||
// write the results
|
||
#ifdef _MSC_VER
|
||
for (std::map<string, vector<int> >::const_iterator it = ret.begin();
|
||
#else
|
||
for (map<string, vector<int> >::const_iterator it = ret.begin();
|
||
#endif
|
||
it != ret.end(); ++it) {
|
||
// write the word
|
||
cout << it->first << " occurs on line(s): ";
|
||
|
||
// followed by one or more line numbers
|
||
#ifdef _MSC_VER
|
||
std::vector<int>::const_iterator line_it = it->second.begin();
|
||
#else
|
||
vector<int>::const_iterator line_it = it->second.begin();
|
||
#endif
|
||
cout << *line_it; // write the first line number
|
||
|
||
++line_it;
|
||
// write the rest of the line numbers, if any
|
||
while (line_it != it->second.end()) {
|
||
cout << ", " << *line_it;
|
||
++line_it;
|
||
}
|
||
// write a new line to separate each word from the next
|
||
cout << endl;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
#include <map> // 引入 map 容器,用于存储每个单词及其出现的行号
|
||
#include <iostream> // 引入标准输入输出流库
|
||
#include <string> // 引入字符串库
|
||
#include <vector> // 引入动态数组库,用于存储每一行的单词
|
||
|
||
#include "split.h" // 引入自定义的 split.h 库,假设包含用于分割字符串的函数
|
||
|
||
using std::cin; // 使用标准输入流
|
||
using std::cout; // 使用标准输出流
|
||
using std::endl; // 使用换行符
|
||
using std::getline; // 使用getline函数读取整行输入
|
||
using std::istream; // 使用输入流
|
||
using std::string; // 使用字符串类型
|
||
using std::vector; // 使用vector容器
|
||
using std::map; // 使用map容器
|
||
|
||
// xref函数:用来查找每个单词在文本中出现的行号
|
||
// 参数:输入流 in 和一个函数指针 find_words,用于分割每行的单词(默认为 split 函数)
|
||
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; // 用map来存储每个单词及其对应的行号
|
||
|
||
// 按行读取输入
|
||
while (getline(in, line)) {
|
||
++line_number; // 增加行号
|
||
|
||
// 调用find_words函数将一行文本分割成单词
|
||
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
|
||
}
|
||
|
||
int main()
|
||
{
|
||
// 调用 xref 函数,默认使用 split 来分割单词
|
||
map<string, vector<int> > ret = xref(cin);
|
||
|
||
// 输出结果
|
||
for (map<string, vector<int> >::const_iterator it = ret.begin(); it != ret.end(); ++it) {
|
||
// 输出单词
|
||
cout << it->first << " occurs on line(s): ";
|
||
|
||
// 获取并输出单词出现的行号
|
||
vector<int>::const_iterator line_it = it->second.begin();
|
||
cout << *line_it; // 输出第一个行号
|
||
|
||
++line_it;
|
||
// 输出其余的行号
|
||
while (line_it != it->second.end()) {
|
||
cout << ", " << *line_it;
|
||
++line_it;
|
||
}
|
||
// 换行
|
||
cout << endl;
|
||
}
|
||
|
||
return 0; // 程序结束
|
||
}
|
||
|