C++でmapを書いててinsertしまくってましたが、
あれれ?Javaと挙動が違うということに気付きました。
mapでinsertするとC++ではキーが重複したときに、
insertされず、valueが上書きされない。
一方、Javaのほうはputしたときに
最後にputしたものでvalueが上書きされる
というようになっていました。
C++のコード
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { unordered_map<string, int> strmap; string k; int v; while (cin >> k >> v) { if (cin.eof()) // Ctrl+D (Unix/Linux), Ctrl+Z(Windows) { break; } strmap.insert({k, v}); } for (const auto& s : strmap) { cout << s.first << " => " << s.second << '\n'; } return 0; }
実行結果
途中まで入力してCtrl+DまたはCtrl+Zで終了しています
aaa 1 bbb 1 aaa 2 bbb 2 bbb => 1 aaa => 1
お、おう、わざと無理やり最後の値でinsertするってことが
単純にはできないのか…
Javaのコード
package purin; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Test1 { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); Scanner in = new Scanner(System.in); while (in.hasNext()) { String buf = in.nextLine(); String[] bufs = buf.split(" "); map.put(bufs[0], Integer.parseInt(bufs[1])); } for (Map.Entry<String, Integer> m : map.entrySet()) { System.out.println(m.getKey() + " => " + m.getValue()); } if (in != null) { in.close(); } } }
実行結果
aaa 1 bbb 1 aaa 2 bbb 2 aaa => 2 bbb => 2
うん、普段触ってる言語はこっちの動きだ……
C++で同じようなことを実現する方法
※追記 こんなことしなくてよいです!
詳細は id:yasuharu519 さんのコメントを参照ください。
operator[]で要素追加できるなんて盲点でした(´Д` )!!
#include <iostream> #include <string> #include <unordered_map> using namespace std; int main() { unordered_map<string, int> strmap; string k; int v; while (cin >> k >> v) { if (cin.eof()) // Ctrl+D (Unix/Linux), Ctrl+Z(Windows) { break; } // not found if (strmap.find(k) == strmap.end()) { strmap.insert({k, v}); } // found else { strmap[k] = v; } } for (const auto& s : strmap) { cout << s.first << " => " << s.second << '\n'; } return 0; }
実行結果はJavaのと同様なので省略します。
うん。要はちゃんとチェックしろってことですね。
find()で見つからないときは最後の要素の次(iterator::end())を返します。
最後の要素でなくて最後の要素の次ですね。C++を使い慣れている人には常識ですが……。
ここ重要なのでテストに出ます。