MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Rustの基礎 - 集合のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Rustの基礎 - 集合
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == Rustにおける集合とは、HashMapの値の無いキーだけの集まりのようなものである。<br> <br> 複数の集合に共通の要素があるのか、片方にあって片方に無いものは何かといった計算をすることができる。<br> <br> HashSetは標準ライブラリに含まれているが、使用する場合には <code>std::collections::HashSet</code> をインポートする必要がある。<br> <br><br> == 集合の宣言 == HashSetを使用するには、<code>std::collections::HashSet</code> をインポートする必要がある。<br> <br> 集合の要素には、同じ値が複数存在せず、ただ1つだけである。<br> したがって、複数の同じ値を集合の要素に追加しても要素は整理される。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; // 空のHashSetを作成 let mut set_a = HashSet::new(); set_a.insert(1); set_a.insert(3); set_a.insert(5); set_a.insert(7); set_a.insert(9); // 重複を含むHashSetを作成 let mut set_b = HashSet::new(); set_b.insert(1); set_b.insert(1); set_b.insert(1); set_b.insert(3); set_b.insert(5); set_b.insert(7); set_b.insert(8); set_b.insert(5); set_b.insert(6); set_b.insert(6); set_b.insert(3); set_b.insert(3); set_b.insert(9); set_b.insert(7); println!("{:?}", set_b); // 出力 {1, 3, 5, 6, 7, 8, 9} </syntaxhighlight> <br> また、空のHashSetは <code>new</code> メソッドで生成する。<br> <code>from</code> メソッドを使用すると、配列から直接HashSetを生成することもできる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; // 空のHashSetを作成 let set_a: HashSet<i32> = HashSet::new(); // 配列からHashSetを作成 let set_b = HashSet::from([1, 2, 3, 4, 5]); println!("{:?}", set_b); // 出力 {1, 2, 3, 4, 5} </syntaxhighlight> <br> <u>※注意</u><br> <u>HashSet型には、要素の順番が存在しない。</u><br> <u>そのため、複数の要素が含まれている場合、どのような順序で並んでいるのかは不定である。</u><br> <u>また、HashSet型には同じ値の要素は1つしか格納できないため、同じ値を持つ要素は1つにまとめられる。</u><br> <br> 以下の例では、集合の要素として、"H" "a" "p" "p" "y"という5つの文字を要素として集合を作成している。<br> 重複した"p"は1つにまとめられ、順序は不定である。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let mut my_set = HashSet::new(); my_set.insert("H"); my_set.insert("a"); my_set.insert("p"); my_set.insert("p"); my_set.insert("y"); println!("{:?}", my_set); // 出力(順序は不定) {"H", "y", "a", "p"} </syntaxhighlight> <br><br> == 集合のメソッド == ==== 要素の追加 ==== 集合に要素を加えるには、<code>insert</code> メソッドを使用する。<br> <code>insert</code> メソッドは、要素が追加された場合はtrueを返し、既に存在していた場合はfalseを返す。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let mut x = HashSet::new(); x.insert(10); x.insert("Rust"); println!("{:?}", x); // 出力(順序は不定) {10, "Rust"} </syntaxhighlight> <br> ==== 要素の削除 ==== また、集合の要素を削除するには、<code>remove</code> メソッドを使用する。<br> <code>remove</code> メソッドは、要素が削除された場合はtrueを返し、要素が存在しなかった場合はfalseを返す。<br> <br> 集合の要素を全て削除するには、<code>clear</code> メソッドを使用する。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let mut x = HashSet::from([3, 1, 5, 4, 2]); x.remove(&5); println!("{:?}", x); x.clear(); println!("{:?}", x); // 出力 (順序は不定) {1, 2, 3, 4} {} </syntaxhighlight> <br> removeメソッドは、要素が存在しない場合でもパニックを起こさず、falseを返すだけである。<br> これは、Pythonのdiscard関数と同様の動作である。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let mut color_set = HashSet::from(["Red", "Green", "Blue"]); // 存在しない要素を削除しようとしてもエラーにならない color_set.remove("White"); println!("{:?}", color_set); // 出力 (順序は不定) {"Blue", "Green", "Red"} </syntaxhighlight> <br> ==== 要素の取得 ==== HashSetから任意の要素を1つ取り出すための専用メソッドは存在しない。<br> <br> <code>iter</code> メソッドを使用してイテレータを取得して、<code>next</code> メソッドで要素を取得することができる。<br> ただし、どの要素が取得されるかは不定である。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let mut color_set = HashSet::from(["Red", "Green", "Blue"]); // イテレータから要素を1つ取得 if let Some(&color) = color_set.iter().next() { println!("{}", color); color_set.remove(color); println!("{:?}", color_set); } if let Some(&color) = color_set.iter().next() { println!("{}", color); color_set.remove(color); println!("{:?}", color_set); } // 出力 (順序は不定) Green {"Blue", "Red"} Blue {"Red"} </syntaxhighlight> <br> ==== 要素数の取得 ==== <code>len</code> メソッドは、HashSetに含まれる要素の数を取得することができる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["Red", "Green", "Blue"]); let set2 = HashSet::from([1, 2, 3, 4, 5]); println!("{}", set1.len()); println!("{}", set2.len()); // 出力 3 5 </syntaxhighlight> <br><br> == イテレータを使用して集合に変換する == <code>collect</code> メソッドを使用すれば、配列、ベクター、文字列等のイテレータを持つコレクションから重複する要素を取り除いてHashSetを生成することができる。<br> <br> 以下の例では、重複した要素は整理されている。<br> 文字列の場合は、文字ごとに分解されてHashSetに格納される。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; // 文字列から作成 (文字ごとに分解される) let a: HashSet<char> = "RustRust".chars().collect(); // ベクターから作成 let b: HashSet<&str> = vec!["Rust", "JavaScript", "PHP", "Rust", "JavaScript", "Rust"] .into_iter() .collect(); // 配列から作成 let c: HashSet<&str> = ["Rust", "JavaScript", "PHP", "C", "JavaScript", "Ruby", "Swift"] .into_iter() .collect(); // HashMapのキーからHashSetを作成 use std::collections::HashMap; let mut map = HashMap::new(); map.insert("x", 100); map.insert("y", 200); map.insert("z", 300); let d: HashSet<_> = map.keys().cloned().collect(); println!("{:?}", a); println!("{:?}", b); println!("{:?}", c); println!("{:?}", d); // 出力 (順序は不定) {'R', 'u', 's', 't'} {"Rust", "JavaScript", "PHP"} {"Rust", "JavaScript", "PHP", "C", "Ruby", "Swift"} {"x", "y", "z"} </syntaxhighlight> <br> 配列からHashSetを生成するには、<code>from</code> メソッド または <code>collect</code> メソッドを使用する。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let my_array = ["A", "B", "C"]; // 配列の生成 // fromメソッドを使用 let my_set1 = HashSet::from(my_array); // collectメソッドを使用 let my_set2: HashSet<_> = my_array.into_iter().collect(); println!("{:?}", my_set1); println!("{:?}", my_set2); // 出力 (順序は不定) {"B", "C", "A"} {"B", "C", "A"} </syntaxhighlight> <br> ベクターからHashSetを作成するには、<code>collect</code> メソッドを使用する。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let my_vec = vec!["A", "B", "C"]; // ベクターの生成 let my_set: HashSet<_> = my_vec.into_iter().collect(); println!("{:?}", my_set); // 出力 (順序は不定) {"B", "C", "A"} </syntaxhighlight> <br> 範囲 (Range) からHashSetを生成するには、<code>collect</code> メソッドを使用する。<br> <br> Rustの範囲 (Range) とは、開始値から終了値までの連続した数値を表すイテレータである。<br> 範囲は、<code>開始値..終了値</code> という形式で記述する。<br> 終了値は範囲に含まれない。<br> <br> <code>開始値..=終了値</code> という形式では、終了値も範囲に含まれる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; // 0〜9までの範囲からHashSetを作成 let my_set: HashSet<_> = (0..10).collect(); println!("{:?}", my_set); // 出力 (順序は不定) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} </syntaxhighlight> <br><br> == 集合の演算 == ==== 積集合 ==== 積集合は、両方の集合に共通する要素からなる集合である。<br> <code>&</code> 演算子 または <code>intersection</code> メソッドを使用して求めることができる。<br> <code>intersection</code> メソッドはイテレータを返すため、<code>collect</code> メソッドで新しいHashSetに変換する必要がある。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let a = HashSet::from([1, 2, 3]); let b = HashSet::from([2, 3, 4]); // &演算子を使用 let c = &a & &b; // intersectionメソッドを使用 let d: HashSet<_> = a.intersection(&b).cloned().collect(); println!("{:?}", c); println!("{:?}", d); // 出力(順序は不定) {2, 3} {2, 3} </syntaxhighlight> <br> ==== 和集合 ==== 和集合は、少なくともどちらかの集合に要素が含まれている集合である。<br> <code>|</code> 演算子 または <code>union</code> メソッドを使用して求めることができる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let a = HashSet::from([1, 2, 3]); let b = HashSet::from([2, 3, 4]); // |演算子を使用 let c = &a | &b; // union()メソッドを使用 let d: HashSet<_> = a.union(&b).cloned().collect(); println!("{:?}", c); println!("{:?}", d); // 出力(順序は不定) {1, 2, 3, 4} {1, 2, 3, 4} </syntaxhighlight> <br> ==== 差集合 ==== 差集合は、一方には含まれているがもう一方には含まれていない要素の集合である。<br> <br> <code>-</code> 演算子 または <code>difference</code> メソッドで求めることができる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let a = HashSet::from([1, 2, 3]); let b = HashSet::from([2, 3, 4]); // -演算子を使用 let c = &a - &b; // differenceメソッドを使用 let d: HashSet<_> = a.difference(&b).cloned().collect(); println!("{:?}", c); println!("{:?}", d); // 出力 (順序は不定) {1} {1} </syntaxhighlight> <br> ==== XOR (対称差集合) ==== XORは、どちらか片方に含まれるが両方には含まれない要素の集合である。<br> <br> <code>^</code> 演算子 または <code>symmetric_difference</code> メソッドで求めることができる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let a = HashSet::from([1, 2, 3]); let b = HashSet::from([2, 3, 4]); // ^演算子を使用 let c = &a ^ &b; // symmetric_differenceメソッドを使用 let d: HashSet<_> = a.symmetric_difference(&b).cloned().collect(); println!("{:?}", c); println!("{:?}", d); // 出力 (順序は不定) {1, 4} {1, 4} </syntaxhighlight> <br><br> == 集合と他の集合との関係 == 集合と集合が等しいかどうか、また、集合が他の集合の部分集合かどうか等、集合と他の集合との関係を確認する。<br> <br> ==== 集合が他の集合と等しいかどうか ==== 比較演算子の <code>==</code> または <code>!=</code> で比較することができる。<br> <br> 集合aの要素が集合bに全て含まれており、集合bの要素が集合aに全て含まれている場合、trueとなる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["A", "B", "C"]); let set2 = HashSet::from(["B", "C", "A"]); println!("{}", set1 == set2); // 出力 true </syntaxhighlight> <br> ==== 部分集合 ==== <code>is_subset</code> メソッドで比較することができる。<br> <br> 集合aの要素が全て集合bに含まれている場合、集合aは集合bの部分集合であるという。<br> <br> 以下の例では、集合set1は集合set2の部分集合であるが、集合set2は集合set1の部分集合ではない。<br> 集合set1と集合set3が等しい場合においても、集合set1は集合set3の部分集合となる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["A", "B"]); let set2 = HashSet::from(["B", "D", "C", "A"]); let set3 = HashSet::from(["B", "A"]); println!("{}", set1.is_subset(&set2)); // set1がset2の部分集合の場合、true println!("{}", set2.is_subset(&set1)); println!("{}", set1.is_subset(&set3)); // 出力 true false true </syntaxhighlight> <br> ==== 真部分集合 ==== Rustには真部分集合を直接判定するメソッドは存在しないが、<code>is_subset</code> メソッド と <code>==</code> 演算子を組み合わせることで判定することができる。<br> <br> 集合aの要素が全て集合bに含まれており、かつ、集合aと集合bが等しくない場合、集合aは集合bの真部分集合であるという。<br> <br> 以下の例では、集合set1は集合set2の真部分集合であり、集合set1と集合set3は真部分集合ではない。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["A", "B"]); let set2 = HashSet::from(["B", "D", "C", "A"]); let set3 = HashSet::from(["A", "B"]); // 真部分集合の判定: 部分集合であり、かつ等しくない println!("{}", set1.is_subset(&set2) && set1 != set2); println!("{}", set2.is_subset(&set1) && set2 != set1); println!("{}", set1.is_subset(&set3) && set1 != set3); // 出力 true false false </syntaxhighlight> <br> ==== 超集合 ==== <code>is_superset</code> メソッドで比較することができる。<br> <br> 集合bの要素が全て集合aに含まれている場合、集合aは集合bの超集合であるという。<br> <br> 以下の例では、集合set1は集合set2の超集合ではないが、集合set2は集合set1の超集合である。<br> 集合set1と集合set3が等しい場合も、集合set1は集合set3の超集合となる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["A", "B"]); let set2 = HashSet::from(["B", "D", "C", "A"]); let set3 = HashSet::from(["B", "A"]); println!("{}", set1.is_superset(&set2)); println!("{}", set2.is_superset(&set1)); println!("{}", set1.is_superset(&set3)); println!("{}", set3.is_superset(&set1)); // 出力 false true true true </syntaxhighlight> <br> ==== 真超集合 ==== Rustには真超集合を直接判定するメソッドは存在しないが、<code>is_superset</code> メソッド と <code>==</code> 演算子を組み合わせることで判定することができる。<br> <br> 集合bの要素が全て集合aに含まれており、かつ、集合aと集合bが等しくない場合、集合aは集合bの真超集合であるという。<br> <br> 以下の例では、集合set1は集合set2の真超集合ではないが、集合set2は集合set1の真超集合である。<br> また、集合set1と集合set3が等しい場合も真超集合ではない。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["A", "B"]); let set2 = HashSet::from(["B", "D", "C", "A"]); let set3 = HashSet::from(["A", "B"]); // 真超集合の判定: 超集合であり、かつ等しくない println!("{}", set1.is_superset(&set2) && set1 != set2); println!("{}", set2.is_superset(&set1) && set2 != set1); println!("{}", set1.is_superset(&set3) && set1 != set3); // 出力 false true false </syntaxhighlight> <br> ==== 互いに素 ==== <code>is_disjoint</code> メソッドで比較することができる。<br> <br> 集合aと集合bが同じ要素を1つも持たない時、集合aは集合bと互いに素であるという。<br> <br> 以下の例では、集合set1は集合set2は共通の要素がないので互いに素であるが、<br> 集合set1と集合set3、および、集合set2と集合set3は共通する要素があるため互いに素ではない。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let set1 = HashSet::from(["A", "B"]); let set2 = HashSet::from(["C", "D", "E"]); let set3 = HashSet::from(["A", "C"]); println!("{}", set1.is_disjoint(&set2)); println!("{}", set1.is_disjoint(&set3)); println!("{}", set2.is_disjoint(&set3)); // 出力 true false false </syntaxhighlight> <br><br> == 集合に指定した値と同じ要素が含まれているか確認する == 集合に対して、指定した値と同じ要素が含まれているかどうか確認することもできる。<br> <br> 要素が含まれているかどうかを確認するには、<code>contains</code> メソッドを使用する。<br> <br> <code>contains</code> メソッドは、集合の要素に指定した値と同じ値の要素が存在する場合はtrue、存在しない場合はfalseとなる。<br> 否定形を使用したい場合は、<code>!</code> 演算子を使用して、containsメソッドの結果を反転させる。<br> <syntaxhighlight lang="rust"> use std::collections::HashSet; let my_set = HashSet::from(["A", "B", "C"]); println!("{}", my_set.contains("A")); println!("{}", my_set.contains("D")); println!("{}", !my_set.contains("D")); // 出力 true false true </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:Rust]]
Rustの基礎 - 集合
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse