1

文字列のベクトルが2つあり、両方に存在する文字列を見つけて、3番目のベクトルに共通の要素を入力します。編集:物事が明確になるように、それぞれの出力を含む完全なコードリストを追加しました。

  std::cout << "size " << m_HLTMap->size() << std::endl;

  /// Vector to store the wanted, present and found triggers
  std::vector<std::string> wantedTriggers;
  wantedTriggers.push_back("L2_xe25");
  wantedTriggers.push_back("L2_vtxbeamspot_FSTracks_L2Star_A");
  std::vector<std::string> allTriggers;

  // Push all the trigger names to a vector
  std::map<std::string, int>::iterator itr = m_HLTMap->begin();
  std::map<std::string, int>::iterator itrLast = m_HLTMap->end();
  for(;itr!=itrLast;++itr)
  {
    allTriggers.push_back((*itr).first);
  }; // End itr

  /// Sort the list of trigger names and find the intersection
  /// Build a typdef to make things clearer
  std::vector<std::string>::iterator wFirst = wantedTriggers.begin();
  std::vector<std::string>::iterator wLast = wantedTriggers.end();
  std::vector<std::string>::iterator aFirst = allTriggers.begin();
  std::vector<std::string>::iterator aLast = allTriggers.end();

  std::vector<std::string> foundTriggers;

  for(;aFirst!=aLast;++aFirst)
  {
    std::cout << "Found:" << (*aFirst) << std::endl; 
  };

  std::vector<std::string>::iterator it;

  std::sort(wFirst, wLast);
  std::sort(aFirst, aLast);
  std::set_intersection(wFirst, wLast, aFirst, aLast, back_inserter(foundTriggers));

  std::cout << "Found this many triggers: " << foundTriggers.size() << std::endl;
  for(it=foundTriggers.begin();it!=foundTriggers.end();++it)
  {
    std::cout << "Found in both" << (*it) << std::endl;
  }; // End for intersection

出力は次のようになります

これが部分的な出力です。ベクトルには1000を超える要素があるため、完全な出力は含めませんでした。

Found:L2_te1400
Found:L2_te1600
Found:L2_te600
Found:L2_trk16_Central_Tau_IDCalib
Found:L2_trk16_Fwd_Tau_IDCalib
Found:L2_trk29_Central_Tau_IDCalib
Found:L2_trk29_Fwd_Tau_IDCalib
Found:L2_trk9_Central_Tau_IDCalib
Found:L2_trk9_Fwd_Tau_IDCalib
Found:L2_vtxbeamspot_FSTracks_L2Star_A
Found:L2_vtxbeamspot_FSTracks_L2Star_B
Found:L2_vtxbeamspot_activeTE_L2Star_A_peb
Found:L2_vtxbeamspot_activeTE_L2Star_B_peb
Found:L2_vtxbeamspot_allTE_L2Star_A_peb
Found:L2_vtxbeamspot_allTE_L2Star_B_peb
Found:L2_xe25
Found:L2_xe35
Found:L2_xe40
Found:L2_xe45
Found:L2_xe45T
Found:L2_xe55
Found:L2_xe55T
Found:L2_xe55_LArNoiseBurst
Found:L2_xe65
Found:L2_xe65_tight
Found:L2_xe75
Found:L2_xe90
Found:L2_xe90_tight
Found:L2_xe_NoCut_allL1
Found:L2_xs15
Found:L2_xs30
Found:L2_xs45
Found:L2_xs50
Found:L2_xs60
Found:L2_xs65
Found:L2_zerobias_NoAlg
Found:L2_zerobias_Overlay_NoAlg
Found this many triggers: 0

考えられる理由

私は自分のコードをコンパイルする方法が原因だと思い始めています。私は現在、スタンドアロンのコンパイルを行う代わりに、ROOT(物理データ分析フレームワーク)を使用してコンパイルしています。STLアルゴリズムライブラリではうまく機能しないように感じます。特に、コードが機能しているように見える人が多いことを考えると、これが問題の原因です。スタンドアロンのコンパイルと再実行を試みます。

4

3 に答える 3

5

foundTriggers.begin()出力引数として空で、を渡しfoundTriggersても、出力はにプッシュされませんfoundTriggers。代わりに、サイズを変更せずにイテレータをベクトルの終わりを超えてインクリメントし、メモリをランダムに破壊します。

挿入イテレータを使用する場合:

std::set_intersection(wFirst, wLast, aFirst, aLast, 
    std::back_inserter(foundTriggers));

更新:コメントで指摘されているように、ベクトルは少なくとも結果に対して十分な大きさになるようにサイズ変更されているため、コードは機能するはずです。交差点の終わりを示すためにから返されたイテレータを使用する必要があることに注意してset_intersectionください。コードはそれを無視するため、出力の最後に残っている空の文字列も繰り返し処理します。

交差点が実際に空であるかどうかを確認できるように、完全なテストケースを投稿していただけますか?

于 2013-02-04T14:04:15.443 に答える
4

結局のところ、あなたのallTrigersベクトル空です。itrマップを埋めるときに、マップの先頭にリセットすることはありません。

編集:

実際には、リセットすることはありませんaFirst

for(;aFirst!=aLast;++aFirst)
  {
    std::cout << "Found:" << (*aFirst) << std::endl; 
  };

  // here aFirst == aLast

  std::vector<std::string>::iterator it;

  std::sort(wFirst, wLast);
  std::sort(aFirst, aLast);  // **** sorting empty range ****
  std::set_intersection(wFirst, wLast, aFirst, aLast, back_inserter(foundTrigger));
                               //      ^^^^^^^^^^^^^^
                               // ***** empty range *****

変数の範囲を絞り込むことがなぜ良い習慣であるかが理解できたと思います。

于 2013-02-04T14:25:02.090 に答える
1

の戻り値を使用することはありませんset_intersection。この場合、戻っfoundIteratorsた後set_intersection、またはforループの上限としてサイズ変更に使用できます。それ以外の場合、コードは機能しているようです。完全にコンパイル可能なプログラムとその実際の出力を確認できますか?

于 2013-02-04T14:15:18.163 に答える