0

コードはC++入門書(3番目)からのものです。エラーは次のとおりです。

* filterString.cpp:関数'int main()':filterString.cpp:32:68:エラー:'__gnu_cxx :: __ normal_iterator *、std ::vector>>'を'std:: string *{akastdに変換できません::basic_string }'初期化中

plsは私がエラーを分析するのを手伝ってくれます、ありがとう。

コード:

#include <string>
#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>

using namespace std;

template <class InputIterator>
void filter_string(InputIterator first, InputIterator last, string filt_elems =  string("\",?.")) {
    for (; first != last; first++){
        string:: size_type pos = 0;
        while ((pos = (*first).find_first_of(filt_elems, pos)) != string::npos)
            (*first).erase(pos, 1);
    }
}

bool length_less (string s1, string s2) {
return s1.size() < s2.size();
}

int main() {
    istream_iterator<string> input(cin), eos;
    vector<string> text;

    copy(input, eos, back_inserter(text));

    string filt_elems("\",.?;:");
    filter_string(text.begin(), text.end(), filt_elems);
    int cnt = text.size();

    string *max = max_element(text.begin(), text.end(), length_less);
    int len = max->size();

    cout << "The number of words read is " << cnt << endl;
    cout << "The longest word has a length of " << len << endl;
    cout << "The longest word is " << *max << endl;

    return 0;
}
4

3 に答える 3

1

32行目で、

std::max_element(text.begin(), text.end(), length_less);

この関数は、文字列ではなく、検索された範囲で最大の要素が最初に出現する位置をアドレス指定する順方向イテレータを返します。

この行の代わりにできること:

string *max = max_element(text.begin(), text.end(), length_less);

あなたはこれをしなければなりません、

//First find the index of the max_element , by subtracting the forward iterator you get from calling max_element from the iterator for first element .

       int index=max_element(text.begin(), text.end(), length_less) - text.begin();

//And then find string stored on that index.

       string *max = text.at(index);
于 2012-10-27T01:56:57.443 に答える
0

これは面白い。イテレータはポインタのように動作しますが、正確ではありません。特に、イテレータをポインタに変換することはできません。

ただし、このコードを変更して、イテレータを一種の文字列*ポインタとして使用することができます。

vector<string>::iterator max = max_element(text.begin(), text.end(), length_less);

これは、maxが文字列へのポインタではなく、文字列のベクトルへのイテレータであることを宣言します。これは、max_elementアルゴリズムが文字列のベクトルに適用されたときに返されるものです。

ポインタを使用することもできますが、それは悪い習慣です。アイデアをテストするためだけに、次のことができます。

string *max = &*max_element(text.begin(), text.end(), length_less);

* max_element(...)は、返されたイテレータが指す文字列への参照を返し(実際のポインタを逆参照するのと同じように)、&はその文字列への(文字列*)ポインタを作成します。

ベクトルの構造変更はそのポインタを静かに無効にする可能性があるため、これは問題を引き起こします。その後のポインタの使用は、「ランダム」メモリを文字列オブジェクトとして扱うことです。さらに悪いことに、テスト中に機能し、ソフトウェアが出荷されるまで失敗しない可能性があります。

イテレータの適切な実装では、無効化を検出して例外をスローする必要があります。予測可能な失敗は、ランダムなメルトダウンよりも優れています。

于 2012-10-27T02:51:28.307 に答える
0

OK、それで私は船外に出ました。これが、ラムダと自動を使用したより現代的なソリューションだと私が思うものです。わかりやすいかどうかは他の人に任せます。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <string>
#include <vector>

using namespace std;

template <class InputIterator>
void filter_string(InputIterator first, InputIterator last, 
                   const string filt_elems = const string("\",?.")) 
{
    for_each(first, last, 
        [filt_elems](string& s)
        {
            s.erase(
                // Shift valid characters up before erasing the undesirable
                remove_if(s.begin(), s.end(), 
                    [filt_elems](string::value_type c)
                    { return filt_elems.find_first_of(c) != string::npos; }), 
                s.end());
        });
}

int main()
{
    istream_iterator<string> input(cin);
    istream_iterator<string> eos;

    vector<const string> words;
    copy(input, eos, back_inserter(words));

    const string filt_elems("\",.?;:");
    filter_string(words.begin(), words.end(), filt_elems);
    const int count = words.size();

    // Get a reference to the longest word
    const auto& max_word = *max_element(words.cbegin(), words.cend(), 
        [](const string& lhs, const string& rhs)
        { return lhs.size() < rhs.size(); });
    const int length = max_word.size();

    cout << "The number of words read is " << count << endl;
    cout << "The longest word has a length of " << length << endl;
    cout << "The longest word is " << max_word << endl;

    return 0;
}
于 2012-10-27T05:33:11.200 に答える