とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

アナグラムプログラム改良版 - リストコンテナとマップコンテナの使用

STL―標準テンプレートライブラリによるC++プログラミング 第2版
単語辞書 を調べ,一番大きいアナグラムグループから出力するプログラム。
ps.hpp は以前と同じものを使う。

// P234 ex14-01.cpp
#include<iostream>
#include<string>
#include<fstream>
#include<iterator>
#include<vector>
#include<algorithm>
#include<map>
#include<list>
#include<functional>
#include<utility>
#include"ps.hpp"
int main(){
 using std::cout;
 using std::flush;
 using std::string;
 using std::cin;
 using std::ifstream;
 using std::endl;
 using std::istream_iterator;
 using std::vector;
 using std::copy;
 using std::back_inserter;
 using std::sort;
 using std::map;
 using std::list;
 using std::greater;
 using std::pair;
 using std::adjacent_find;
 using std::find_if;
 using std::not1;
 using std::bind1st;
 using std::ostream_iterator;
 cout << "Anagram group finding program:\n"
  "finds all anagram groups in a dictionary.\n\n"
  "First, enter the name of the file containing\n"
  "the dictionary: " << flush;
 string dictionaryName;
 cin >> dictionaryName;
 ifstream ifs(dictionaryName.c_str());
 if(!ifs.is_open()){
  cout << "Eh? Could not open file named " << dictionaryName << endl;
  return 1;
 }
 cout << "\nReading the dictionary ..." << flush;
 istream_iterator<string> ifsIter(ifs), ifsEnd;
 vector<PS> wordPairs;
 copy(ifsIter, ifsEnd, back_inserter(wordPairs));
 cout << "\nSearching " << wordPairs.size()
  << " words for anagram groups.." << flush;
 sort(wordPairs.begin(), wordPairs.end(), FirstLess());
 typedef vector<PS>::const_iterator PSi;
 typedef pair<PSi, PSi> PPS;
 typedef map<int, list<PPS>, greater<int>> Map;
 Map groups;
 cout << "\n\nThe anagram groups are" << endl;
 for(PSi j = wordPairs.begin(), finis = wordPairs.end(), k;;){
  j = adjacent_find(j, finis, FirstEqual());
  if(j == finis)break;
  k = find_if(j + 1, finis, not1(bind1st(FirstEqual(), *j)));
  if(k - j > 1)groups[k - j].push_back(PPS(j, k));
  j = k;
 }
 for(Map::const_iterator m = groups.begin(), mEnd = groups.end();
  m != mEnd; ++m)
 {
  cout << "\nAnagram groups of size " << m->first << ":\n";
  for(list<PPS>::const_iterator l = m->second.begin(), lEnd = m->second.end();
   l != lEnd; ++l)
  {
   cout << "  ";
   copy(l->first, l->second, ostream_iterator<string>(cout, " "));
   cout << endl;
  }
 }
}