2012-01-21 5 views
1

私のremove_ifは、フィルタにかけられた要素の値でフィルタされていない要素を上書きしているようです。これらのコードの目的は、特定のカテゴリの教師のみをフィルタリングして表示できるようにすることです。 (任意の要素を削除していない) ここ私のベクトルを上書きするC++のremove_if

static string compare; 
static string debug; 

bool filter_Cat (Teacher &t) 
{ 
    return (t.getCat() != compare); 
} 

void filterCat (vector<Teacher> &t) 
{ 
    vector<Teacher>::iterator i; 
    vector<Teacher>::iterator newedited = remove_if(t.begin(), t.end(), filter_Cat); 
    for (i = t.begin(); i != newedited; ++i) 
    { 
    Teacher& te = *i; 
    te.getName(); 
    cout << "\t"; 
    te.getCategory(); 
    cout << "\t"; 
    te.getLocation(); 
    } 
} 

void filterTutorCat(vector<Teacher> &t) 
{ 
    int choice; 
    cout << "No\tCategory" << endl 
     << "1\tEnglish" << endl 
     << "2\tMath" << endl 
     << "3\tScience" << endl 
     << "Choose the category you wish to filter :"; 
    cin >> choice; 
    getline(cin, debug); 

    if(choice <= 3 && choice > 0) 
    { 
     if (choice == 1) 
     { 
      compare = "English"; 
      filterCat(t); 
     } 
     if (choice == 2) 
     { 
      compare = "Math"; 
      filterCat(t); 
     } 
     if (choice == 3) 
     { 
      compare = "Science"; 
      filterCat(t); 
     } 

    } 
    else 
    { 
     cout << "Invalid Option" << endl; 
    } 
} 
+1

入力と予想出力と実際の出力は何ですか? –

+0

コードからわかるように、ユーザーはフィルタリングするカテゴリに1,2または3しか入力できません。予想される出力については、ユーザーが選択したカテゴリの教師しか表示されません。実際の出力は、「比較」と一致するカテゴリを持つオブジェクトが1つしかない場合に出力されますが、「比較」に一致するカテゴリのオブジェクトが2つある場合は、ベクトルのオブジェクトを上書きし始めます。 – delphi316

答えて

2

remove_if shiftts要素は、compare関数がfalseを返す要素を右から左にシフトします。言い換えれば、compareがtrueを返す要素を、compareが返す要素で上書きします。ただし、ベクターのサイズは変更されません。

This reads

は)最初の、最後の範囲から特定の基準を満たすすべての要素を削除します。最初のバージョンはvalueと等しいすべての要素を削除し、2番目のバージョンは述語pがtrueを返すすべての要素を削除します。

消去は、消去される要素が上書きされるように範囲の要素をシフトすることによって行われます。範囲の古い側と新しい側の間の要素には、不特定の値があります。範囲の新しい終わりまでのイテレータが返されます。残っている要素の相対的な順序は保持されます。それでは、あなたがやりたいことのように表現されなければならない

:それはあなたのコードに思わ

void filterCat (vector<Teacher> &v) 
{ 
    for (vector<Teacher>::iterator it = v.begin(); it != v.end() ; ++it) 
    { 
     if (!filter_Cat(*i)) 
     { 
      std::cout << i->getName() <<"\t" << i->getCategory() << std::endl; 
     } 
    } 
} 

getName()ではなく、それは名前を返す必要があり、理想的にそれはやるべきではない名前を出力します。だから私は名前を返すように変更することをお勧めします。 getCategoryについても同じことをしてください。あなたの名前を正しく選択してください。 getName()の場合は、に返す必要があります。 printName()の場合は、の印刷の名前にする必要があります。


また、あなたが書いたコードは良くありません。

  • あなたはグローバル変数を避ける必要があります。
  • if-elseは可能な限り避けてください。より良い方法を学ぶ。
  • 関数オブジェクト(またはファンクタ)について学ぶ必要があります
  • constメンバ関数について学ぶ必要があります。
  • iteratorconst_iteratorの違いとその使い方を理解する必要があります。
  • const参照と非const参照の違いを理解する必要があります。そしてそれらを適切に使用してみてください。

だから私はあなたのようなコードを記述しますコメントで述べたように

//this is functor, not a function 
struct filter_cat 
{ 
    std::string m_cat; //use member data, avoid global variable 
    filter_cat(std::string const & cat) : m_cat(cat) {} 
    bool operator()(Teacher const & t) const //const member function 
    { 
    return (t.getCat() != m_cat); //getCat should be const member function 
    } 
}; 

//pass vector by const reference 
void filterCat (vector<Teacher> const & v, filter_cat filter) 
{ 
    //use const_iterator here, instead of iterator 
    for (vector<Teacher>::const_iterator it = v.begin(); it != v.end() ; ++it) 
    { 
     if (!filter(*i)) 
     { 
      //getName and getCategory should be const member function 
      std::cout << i->getName() <<"\t" << i->getCategory() << std::endl; 
     } 
    } 
} 

void filterTutorCat(vector<Teacher> const &t) 
{ 
    int choice; 
    cout << "No\tCategory" << endl 
     << "1\tEnglish" << endl 
     << "2\tMath" << endl 
     << "3\tScience" << endl 
     << "Choose the category you wish to filter :"; 
    cin >> choice; 
    getline(cin, debug); 

    //avoid if-else as much as possible, learn better ways! 
    std::string cats[] = {"English", "Math", "Science"}; 

    if(choice <= 3 && choice > 0) 
    { 
      filterCat(v, filter_cat(cats[choice-1])); 
    } 
    else 
    { 
     cout << "Invalid Option" << endl; 
    } 
} 

getCatgetNamegetCategoryはconstメンバ関数でなければなりません。実際には、getCategoryがカテゴリを返す場合は、getCatも必要ありません。

解決しました。

+1

+1簡単な明快な言語の説明のために。コンテナ内の要素の数は、明示的に消去されない限り変化しません。 –

+0

私はあなたのコーディングを理解していますが、アルゴリズムでこれを行う方法はありますか? – delphi316

+0

@NewUserSeekingHelp:方法があっても、それを避けるには十分複雑です。 ''を使って直接行う方法はありません。また、コードの書き直しで示唆したように、コード全体やコード内の他の問題にもっと焦点を当てる必要があります。 – Nawaz

1

remove_ifがfilter_Cat容器の開始時に偽を返しているの値を収集するコードの一部です。コンテナ内の要素の数は減らされませんが、返される範囲を超えた要素の値については保証されません。したがって、remove_ifを使用すると値が失われます。

+0

それでは、私の場合のオプション? – delphi316

+0

@NewUserSeekingHelp:ループの中にテストを表示し、それを表示するかどうかを決定するループです。 –

+0

このシナリオに適したアルゴリズムを適用できますか? – delphi316

関連する問題