C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で配列内の重複しない(一意な)要素の合計を求める方法

問題の概要

いくつかの要素を含む配列 A があるとします。この配列から、すべての一意な(重複しない)要素の合計を求める必要があります。

例えば、配列が A = [5, 12, 63, 5, 33, 47, 12, 63] の場合を考えてみましょう。このとき、一意な要素は「5, 12, 63, 33, 47」であり、その合計は 160 になります。重複している要素は、一度合計に加算された後は単純に無視されます。

解決のアプローチ

この問題は、C++の unordered_set(ハッシュセット)を使うことで効率的に解決できます。基本的な考え方は以下のとおりです。

  • forループを1回だけ実行して配列を走査する
  • 初めて現れた値であれば、合計変数に加算する
  • 同時にハッシュテーブル(unordered_set)にその値を記録する
  • 2回目以降に同じ値が現れた場合は、すでにセットに存在するため無視する

ハッシュセットによる検索・挿入は平均 O(1) で行えるため、全体の計算量は O(n) となり、非常に高速に処理できます。

コード例

#include<iostream>
#include<unordered_set>
using namespace std;

int getNonRepeatSum(int arr[], int n) {
    int sum = 0;
    unordered_set<int> u_set;
    for (int i = 0; i < n; i++) {
        // まだセットに存在しない値なら加算して登録
        if (u_set.find(arr[i]) == u_set.end()) {
            sum += arr[i];
            u_set.insert(arr[i]);
        }
    }
    return sum;
}

int main() {
    int arr[] = {5, 12, 63, 5, 33, 47, 12, 63};
    int n = sizeof(arr) / sizeof(int);
    cout << "Sum is: " << getNonRepeatSum(arr, n);
}

実行結果

Sum is: 160

コードのポイント

  • u_set.find(arr[i]) == u_set.end() によって、その値がまだセットに存在しないこと(=初登場であること)を判定しています。
  • 初登場の値のみ sum に加算し、insert() でセットに登録することで、以降の重複を自動的に排除できます。
  • ソート不要・二重ループ不要のため、要素数が多い配列でも高いパフォーマンスを発揮します。
  1. C++で配列のすべての部分集合(サブセット)の合計を求める方法

    問題の概要整数の配列が与えられたとき、その部分集合(サブセット)から作り出せるすべての異なる合計値を求め、昇順に出力する方法を解説します。この問題は、配列の要素の合計値が比較的小さい場合に、動的計画法を使って効率的に解くことができます。例として、配列 [1, 2, 3] を考えてみましょう。考えられるすべての部分集合は {}、{1}、{2}、{3}、{1, 2}、{2, 3}、{1, 3}、{1, 2, 3} であり、それぞれの合計値は 0, 1, 2, 3, 3, 5, 4, 6 となります。重複する値を取り除くと、出力は 0, 1, 2, 3, 4, 5, 6 となります。アプローチ:動的

  2. C++で2つの配列の合計を等しくする要素スワップのペアを見つける方法

    要素数が異なる2つの配列があるとします。このとき、1つ目の配列に含まれる要素 x と、2つ目の配列に含まれる要素 y からなるペアを見つけます。このペアを選んで2つの配列間で要素を入れ替えた結果、両方の配列の合計が等しくなるようにするのが目的です。例として、配列 A が [4, 1, 2, 2, 1, 1]、配列 B が [3, 3, 6, 3] を持っている場合を考えてみましょう。A の合計は 11、B の合計は 15 です。ここで (1, 3) というペアを選び、これらの値を2つの配列間で入れ替えると、合計は次のようになります。A: [4, 3, 2, 2, 1, 1] → 合計 13B: