自分で改造したプログラムがわかりません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ただの屍のようだ

自分で改造したプログラムがわかりません

#1

投稿記事 by ただの屍のようだ » 12年前

元のサンプルプログラム:diction.txt(単語20159個)からアルファベットの組み合わせが同じの単語グループをすべて抜き出す。
改造後のプログラム:diction.txt(単語20159個)から引数で指定した単語とアルファベットの組み合わせが同じのグループを抜き出す。
疑問に思う点が主に2つ。
1.PS.hの比較関数はどうしてメンバ関数ではなく、関数オブジェクトなのですか?(これは元々で一切変更を加えてません)
2.メインプログラムの27行目がどうしてうまくグループを抜き出せるのですか?(これは自分が書きましたが、sortせずともうまくいったのは予想外です)

コード:

// PS.h ヘッダ
#ifndef _PAIR_IN_STRUCT
#define _PAIR_IN_STRUCT
#include<string>
#include<functional>
#include<algorithm>
using namespace std;

struct PS : pair<string,string>{
	PS() : pair<string,string>(string(),string()){}
	PS(const string &s) : pair<string,string>(s,s){ sort(first.begin(),first.end());}
	operator string() const{return second;}
};

struct FirstLess : binary_function<PS,PS,bool>{
	bool operator()(const PS &a,const PS &b){return a.first < b.first;}
}firstLess;
struct FirstEqual : binary_function<PS,PS,bool>{
	bool operator()(const PS &a,const PS &b){return a.first == b.first;}
}firstEqual;

#endif

コード:

#include<iostream>
#include<iomanip>
#include<vector>
#include<iterator>
#include<fstream>
#include "PS.h";
#include <cassert>
using namespace std;

const int DICTION_SIZE = 20159;

ostream &error_message(ostream &stream){
	stream << "Could not find the word";
	return stream;
}

int main(int argc,char *argv[]){
	char path[] = "C:\\Users\\Owner\\Desktop\\src\\diction.txt";
	ifstream ifs(path);
	assert(ifs!=NULL && argc>1);
	vector<PS> dictionary;

	dictionary.reserve(DICTION_SIZE);
	copy(istream_iterator<string>(ifs),istream_iterator<string>(),back_inserter(dictionary));
	sort(dictionary.begin(),dictionary.end(),firstLess);
	while(--argc){
		pair<vector<PS>::iterator,vector<PS>::iterator> pi = equal_range(dictionary.begin(),dictionary.end(),string(*++argv),firstLess);
		if(pi.first==pi.second)	cout << error_message;
		copy(pi.first,pi.second,ostream_iterator<string>(cout,"\t"));
		cout << endl;
	}
	return 0;
}


ただの屍のようだ

Re: 自分で改造したプログラムがわかりません

#2

投稿記事 by ただの屍のようだ » 12年前

n十年プログラミング経験があっても、C++のジェネリックプログラミングスタイルを初見で理解するには難しいですね。
(だからといっていちいちコメント書いたら、コメントだらけになってしまいます)
元のコードを読み直したら、メインプログラムで関数アダプタが使われていました。よって、質問1は解決しました。
質問2は引き続き、回答を待ちます。

アバター
a5ua
記事: 199
登録日時: 14年前

Re: 自分で改造したプログラムがわかりません

#3

投稿記事 by a5ua » 12年前

sortせずともうまくいったのは予想外です
PSのコンストラクタ(PS.h 11行目)で文字列ペアのfirst要素をソートしていますよ。
例えば、"the"という文字列からは、("eht", "the")というPSのオブジェクトが生成されます。

ただの屍のようだ

Re: 自分で改造したプログラムがわかりません

#4

投稿記事 by ただの屍のようだ » 12年前

いいところに聞いてくれましたね!
その通りです、渡したのはstring()のはずなのに、どうやら受けた先ではPS(const string&)のようです。
そこを説明してほしい

アバター
a5ua
記事: 199
登録日時: 14年前

Re: 自分で改造したプログラムがわかりません

#5

投稿記事 by a5ua » 12年前

//説明になっているかわかりませんが。。。

コード:

vector<PS> dictionary;

PS ps(string("qw4iqty"));
dictionary.push_back(ps);
上のように、dictionaryに要素を追加するには、PS型のオブジェクトを作らなければならないように見えます。

しかし、実際には以下のコードで要素を追加できます。
これは、PS(const string &s)が「変換コンストラクタ」として暗黙的に呼び出されているためです。

コード:

vector<PS> dictionary;
dictionary.push_back(string("qw4iqty"));
ちなみに、変換コンストラクタが暗黙的に呼び出されないようにするには、コンストラクタの宣言時にexplicitをつけます。
(こうするとコンパイルエラーになるはずです)

コード:

explicit PS(const string &s) : ...(以下略)

ただの屍のようだ

Re: 自分で改造したプログラムがわかりません

#6

投稿記事 by ただの屍のようだ » 12年前

まさか、暗黙のコンストラクタ呼び出しに気付かなかったとは。。。
ありがとうございます。

ただの屍のようだ

Re: 自分で改造したプログラムがわかりません

#7

投稿記事 by ただの屍のようだ » 12年前

さて、ネットワークの勉強で精一杯、ジェネリックプログラミングを本格的に学習できるのはおそらく11月以降となるでしょう。
ですが、これからの質問となるコードはすべてジェネリックプログラミングスタイルがベースとなります。
親切なみなさんならきっと答えてくれると信じています。よろしくおねがいします。

閉鎖

“C言語何でも質問掲示板” へ戻る