在文本文件中找到并标记单词

时间:2012-11-27 19:17:22

标签: c++

我需要阅读500字以上的文本文件(来自报纸的真实世界文章等)并找到并标记这样的<location> word <location/>,然后在屏幕上打印整篇文章。我现在正在使用boost regex并且工作正常。我想尝试使用列表或数组或其他数据结构来获得状态和主要城市的列表,并搜索它们并与aticle进行比较。现在我正在使用阵列,但我愿意使用任何东西。有什么想法或线索吗?

#include <boost/regex.hpp>
#include <iostream>
#include <string>
#include <boost/iostreams/filter/regex.hpp>
#include <fstream>


using namespace std;

int main()
{
string cities[389];
string states [60];
string filename, line,city,state;
ifstream file,cityfile, statefile;
int i=0;
int j=0;
cityfile.open("c:\\cities.txt");
while (!cityfile.eof())
{

    getline(cityfile,city);
        cities[i]=city; 
        i++;
    //for (int i=0;i<500;i++)
        //file>>cities[i];
}
cityfile.close();

statefile.open("c:\\states.txt");
while (!statefile.eof())
{
    getline(statefile,state);
        states[j]=state; 
    //for (int i=0;i<500;i++)
    //cout<<states[j];
    j++;
}
statefile.close();
//4cout<<cities[4];






cout<<"Please enter the path and file name "<<endl;
cin>>filename;
file.open(filename);

while (!file.eof())
{
        while(getline(file, line)
        {


        }




        while(getline(file, line))
        {


        //string text = "Hello world";
        boost::regex re("[A-Z/]\.[A-Z\]\.|[A-Z/].*[:space:][A-Z/]|C........a");
        //boost::regex re(
        string fmt = "<locations>$&<locations\>";
        if(boost::regex_search(line, re))
            {
                 string result = boost::regex_replace(line, re, fmt);
                cout << result << endl;
            }
        /*else
            {
                cout << "Found Nothing" << endl;
            }*/

        }
}
file.close();

cin.get(),cin.get();
return 0;

}

2 个答案:

答案 0 :(得分:1)

如果您追求渐近复杂度 - Aho-Corasick algorithm提供线性时间复杂度(O(n+m))(nm是输入字符串的长度)。用于搜索字符串中的字典。

另一种方法是将标记化的单词放在map中(其中值是每个字符串流中的位置的列表),并搜索树中数据中的每个字符串。复杂性为O(|S| * (nlogn + mlogn) )m是搜索字词的数量,n是字符串中的字数,|S|是平均字的长度)

答案 1 :(得分:1)

您可以使用任何具有.find()方法或支持std::find()的容器。我使用set,因为set::find()的运行时间不到线性时间。

这是一个完成你所谈论的程序。请注意,解析不是很好,但这不是我想要演示的。您可以继续使用解析器查找单词,并使用set::find()调用来确定它们是否为位置。

#include <set>
#include <string>
#include <iostream>
#include <sstream>

const std::set<std::string> locations { "Springfield", "Illinois", "Pennsylvania" };

int main () {
  std::string line;
  while(std::getline(std::cin, line)) {
    std::istringstream iss(line);
    std::string word;
    while(iss >> word) {
      if(locations.find(word) == locations.end())
        std::cout << word << " ";
      else
        std::cout << "<location>" << word << "</location> ";
    }
    std::cout << "\n";
  }
}