宜しくお願いいたします。
全ての文章に対して探索を行い、全て探索不一致の場合
探索単語と、探索した文を表示させるコードを、このように書きました、
とりあえず、この内側の繰り返し部分
for (ITER itr = senVec.begin(); itr != senVec.end(); itr++) {
ここをfor_eah構文を用いて書いて見たいのですが、
for_each(senVec.begin(), senVec.emd(), ここの書き方が分かりません)
お手本を示して頂けないでしょうか。
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <iostream>
//不一致ならtrue一致ならfalseを返却
struct Mismatch {
bool operator()(std::string::size_type pos) const {
return pos == std::string::npos;
}
};
using namespace std;
typedef vector<string>::iterator ITER;
void Show(string Sentence, string Searchwd);
Mismatch m_mismatch;
int main(int argc, char* argv[])
{
//探索対象文
vector<string> senVec;
senVec.push_back(This tutorial has been written for both vi and vim.);
senVec.push_back(It starts with really basics);
senVec.push_back(For every section of this);
//探索単語
vector<string> destVec;
destVec.push_back(tutorial);
destVec.push_back(foo);
destVec.push_back(hoge);
bool bMatch = false;
string::size_type pos;
string sSentence;
string sSearchwd;
for (ITER it = destVec.begin(); it != destVec.end(); it++) {
for (ITER itr = senVec.begin(); itr != senVec.end(); itr++) {
sSentence = *itr;
pos = sSentence.find(*it);
sSearchwd = *it;
if(m_mismatch(pos)) {
bMatch = true;
} else {
bMatch = false;
break;
}
if(bMatch == true) {
Show(sSentence, sSearchwd);
sSentence = sSearchwd = ";
bMatch = false;
}
}
}
return 0;
}
void Show(string Sentence, string Searchwd)
{
cout << 単語 << Searchwd.c_str() << はこの文章に含まれていません <<
Sentence.c_str() << endl;
}
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
template<typename T>
void Show(const T& Sentence, const T& Searchwd) {
cout << 単語 << Searchwd << はこの文章に含まれていません
<< Sentence << endl;
}
struct match {
string target_;
match(const string& target) : target_(target) {}
bool operator()(const string& str) const {
if ( str.find(target_) == string::npos ) {
Show(str,target_);
}
return true;
}
};
struct match_lines {
const vector<string> lines_;
match_lines(const vector<string>& lines) : lines_(lines) {}
bool operator()(const string& target) const {
for_each(lines_.begin(), lines_.end(), match(target));
return true;
}
};
int main() {
//探索対象文
const char* sentences[] = {
This tutorial has been written for both vi and vim.,
It starts with really basics,
For every section of this
};
vector<string> senVec(sentences, sentences+3);
//探索単語
const char* targets[] = { tutorial, foo, hoge };
vector<string> destVec(targets,targets+3);
for_each(destVec.begin(), destVec.end(), match_lines(senVec));
}
επιστημηさん、お世話になります。素晴らしサンプルありがとうございます。
しっかり、動作を追いかけさせて頂きました。
プログラムの流れ
① main() → match_lines
コンストラクタで、探索される側の、vector<string> senVec を引渡し
for_each文の、第一第二引数で、探索単語を、一単語づつ渡す。
② match_lines → match
コンストラクタで探索単語を渡し
for_each文の、第一第二引数で、探索される一行を、渡す。
③ 行を検索単語で走査し、マッチしなければ、表示
ポイント
コンストラクタ、を利用してデータ(①では全体の配列、②では探索単語)を渡している点
だと思います。
この発想と、for_each文を多段で使うという、思考回路が私には欠落しています。
申し訳ないのですが、もう一点お願いがございます。
③ の部分で、現在は、一行づつ、単語を探索し、その行でマッチしなければ、表示すると
いう動作になると思うのですが、これを、全ての行を探索して、全ての行に探索単語が無
かった場合、無かった単語を表示させる動作に変更した場合、どのように書けば良いので
しょうか。
for、if、while構文で書けば、簡単に書けるのですが、関数オブジェクト(for_eachの3
番目)で書こうと思うと、手が止まってしまいます、あつかましいお願い。
申し訳ないのですが、宜しくお願いいたします。
> 全ての行を探索して、全ての行に探索単語が無かった場合、
> 無かった単語を表示させる動作に変更した場合、
> どのように書けば良いのでしょうか。
for_each では(できんことはないけど)かったるいので find_if を使用。
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
struct match {
string target_;
match(const string& target) : target_(target) {}
bool operator()(const string& str) const {
return str.find(target_) != string::npos;
}
};
struct match_lines {
const vector<string>& lines_;
match_lines(const vector<string>& lines) : lines_(lines) {}
bool operator()(const string& target) const {
if ( find_if(lines_.begin(), lines_.end(), match(target)) == lines_.end
() ) {
cout << target << は文章中には含まれていません << endl;
}
return true;
}
};
int main() {
//探索対象文
const char* sentences[] = {
This tutorial has been written for both vi and vim.,
It starts with really basics,
For every section of this
};
vector<string> senVec(sentences, sentences+3);
//探索単語
const char* targets[] = { tutorial, foo, hoge };
vector<string> destVec(targets,targets+3);
cout << 検索対象: << endl;
copy(senVec.begin(), senVec.end(), ostream_iterator<string>(cout,\n));
cout << endl << 検索結果: << endl;
for_each(destVec.begin(), destVec.end(), match_lines(senVec));
}
επιστημη さん、本当にありがとうございます。
> for_each では(できんことはないけど)かったるいので find_if を使用。
なるほど、この場合find_if の方が適切ですね、find_if 自体は、
知らなかったわけではないのですが、適切な使いどころを分かっていないんですよ
ね・・・・orz
この度、お手本を掲示していただき
コンストラクタの使い方が、よく理解できたといいますか、とても良い勉強になりまし、
C++が、すごく良く考えられた言語だと、今更ながら痛感したしだいです。
本当にありがとうございました。
無理くりfor_eachを使ってみた:
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
struct match {
static bool found;
string target_;
match(const string& target) : target_(target) { found = false; }
bool operator()(const string& str) const {
found = found || (str.find(target_) != string::npos);
return true;
}
};
bool match::found;
struct match_lines {
const vector<string>& lines_;
match_lines(const vector<string>& lines) : lines_(lines) {}
bool operator()(const string& target) const {
match pred(target);
if ( !for_each(lines_.begin(), lines_.end(), pred).found ) {
cout << target << は文章中には含まれていません << endl;
}
return true;
}
};
int main() {
/* 変わらず */
}
↑あ、static bool found 改め mutable bool found の方が綺麗かな。