アプリケーション開発ポータルサイト
ServerNote.NET
カテゴリー【C/C++
【C++】2つのvector配列を比較して両方に共通する要素を取り出す【set_intersection】
POSTED BY
2023-01-14

C++には2つのvector配列を比較して両方に共通する要素を取り出してくれる便利な関数set_intersectionがある。

これは、たとえば2人の旅行者が旅程を立てて、立ち寄る駅をリスト化した場合、この関数を使えば、2人が共通で立ち寄る駅は〇駅で、それぞれ〇番目に立ち寄る駅である、などと算出できる。

実践してみたサンプルソースは以下。

C/C++std_set_intersection.cppGitHub Source
//2人の旅程を比較し立ち寄る同じ駅を抽出するサンプル

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

int main(void) {
  std::vector<std::string> ryotei_1 = {"新宿", "西武新宿", "中井", "所沢", "本川越", "川越", "大宮", "池袋"};
  std::vector<std::string> ryotei_2 = {"飯能", "所沢", "池袋", "上野", "秋葉原", "新宿", "中野", "阿佐ヶ谷"};

  //インデックスマップを作成 map[駅名] = 配列インデックス
  std::unordered_map<std::string, int> ryotei_1_map = std::unordered_map<std::string, int>();
  std::unordered_map<std::string, int> ryotei_2_map = std::unordered_map<std::string, int>();
  int i = 0;
  std::for_each(ryotei_1.begin(), ryotei_1.end(), [&](auto &c) {
    ryotei_1_map[c] = i++;
  });
  i = 0;
  std::for_each(ryotei_2.begin(), ryotei_2.end(), [&](auto &c) {
    ryotei_2_map[c] = i++;
  });

  //立ち寄る同じ駅を抽出(ryotei_comに入る)
  //対象配列はあらかじめソートしておかないと機能しない※重要
  std::vector<std::string> ryotei_com = std::vector<std::string>();
  std::sort(ryotei_1.begin(), ryotei_1.end());
  std::sort(ryotei_2.begin(), ryotei_2.end());
  std::set_intersection(ryotei_1.begin(), ryotei_1.end(), ryotei_2.begin(), ryotei_2.end(), std::inserter(ryotei_com, ryotei_com.end()));

  //結果サマリーを出力
  std::cout << "<2人が両方とも立ち寄る駅>" << std::endl;
  std::for_each(ryotei_com.begin(), ryotei_com.end(), [&](auto &c) {
    std::cout << c << " : Aさんが " << ryotei_1_map[c] + 1 << " 番目、Bさんが " << ryotei_2_map[c] + 1 << " 番目に立ち寄る駅。" << std::endl;
  });
}

コンパイル、実行結果

g++ std_set_intersection.cpp

./a.out

<2人が両方とも立ち寄る駅>
所沢 : Aさんが 4 番目、Bさんが 2 番目に立ち寄る駅。
新宿 : Aさんが 1 番目、Bさんが 6 番目に立ち寄る駅。
池袋 : Aさんが 8 番目、Bさんが 3 番目に立ち寄る駅。

元の旅程リストの駅名をキーにした配列インデックスをunordered_mapに保存しておき、共通駅抽出ができたらそのリストから駅名キーをマップから配列インデックスを取得し案内している。色々な業種で実用シーンの多い機能である。

set_intersectionにかける前に、元配列は必ずソートしておかないと機能しない点に注意。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

【キーワード検索】