Объединить два списка слов - PullRequest
1 голос
/ 07 апреля 2011

Я хочу объединить два списка слов в один файл. Все дубликаты должны быть удалены. Каждое слово отделяется новой строкой. Я искал такую ​​программу, но ничего не могу найти. Я ищу правильную вещь? Есть ли реализация этого на c / c ++?

Ответы [ 5 ]

8 голосов
/ 07 апреля 2011
// read input
std::ifstream in( file_path );
typedef std::set< std::string > wordlist_type;
wordlist_type wordlist;
std::string word;

while ( in >> word ) {
    wordlist.insert( word );
}

// repeat with other files to merge more wordlists

// now output to a new file
std::ofstream out( output_path );
for ( wordlist_type::iterator it = wordlist.begin(); it != wordlist.end(); ++ it ) {
    out << * it << '\n';
}
3 голосов
/ 07 апреля 2011

Насколько большие файлы. Если вы можете держать их обоих в памяти, это относительно просто при использовании STL:

std::vector<std::string> v(
        (std::istream_iterator<std::string>( ifile1 )),
        (std::istream_iterator<std::string>()));
v.insert(v.end(),
         std::istream_iterator<std::string>( ifile2 ),
         std::istream_iterator<std::string>());
std::sort( v.begin(), v.end() );
std::copy( v.begin(), std::unique( v.begin(), v.end() ),
           std::ostream_iterator<std::string>( ofile, "\n" ) );

или

std::vector<std::string> v1(
        (std::istream_iterator<std::string>( ifile1 )),
        (std::istream_iterator<std::string>()) );
std::sort( v1.begin(), v1.end() );
v1.erase( std::unique( v1.begin(), v1.end() ), v1.end() );
std::vector<std::string> v2(
        (std::istream_iterator<std::string>( ifile2 )),
        (std::istream_iterator<std::string>()) );
std::sort( v2.begin(), v2.end() );
v2.erase( std::unique( v2.begin(), v2.end() ), v2.end() );
std::set_intersection( v1.begin(), v1.end(),
                       v2.begin(), v2.end(),
                       std::ostream_iterator<std::string>( ofile, "\n" ) );

Если они не вписываются в память, вам, вероятно, придется отсортировать каждый файл (используя system для вызова вашей локальной утилиты), затем выполните объединить вручную:

class FilterDuplicates
{
    std::ostream& myDest;
    std::string myLastOutput;
public:
    Outputter( std::ostream& dest ) : myDest( dest ) {}
    void write( std::string const& word ) const
    {
        if ( word != myLastOutput ) {
            myDest << word;
            myLastOutput = word;
        }
    }
};

ifile1 >> s1;
ifile2 >> s2;
FilterDuplicates out( ofile )
while ( ifile1 && ifile2 ) {
    if ( s1 < s2 ) {
        out.write( s1 );
        ifile1 >> s1;
    } else {
        out.write( s2 );
        ifile2 >> s2;
    }
}
while ( ifile1 ) {
    out.write( s1 );
    ifile1 >> s1;
}
while ( ifile2 ) {
    out.write( s2 );
    ifile2 >> s2;
}
2 голосов
/ 07 апреля 2011
#include <string>
#include <set>
#include <iostream>

int main()
{
    std::set<std::string> s;
    std::string word;
    while (std::cin >> word)
        s.insert(s);
    for (std::set<std::string>::const_iterator i = s.begin(); i != s.end(); ++i)
        std::cout << s << '\n';
}

использование:

cat input1 input2 | program > output
0 голосов
/ 07 апреля 2011

как-то так ...

std::set<std::string> words;    
std::string word;

while(cin >> word)
  if (words.insert(word).second)
    cout << word;

РЕДАКТИРОВАТЬ: упс, слишком хочется упростить ...

0 голосов
/ 07 апреля 2011

Если у вас есть доступ к Unix

cat file1 file2 | sort | uniq > file3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...