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

配列内で複数回出現する要素を見つける方法【C++実装例】

問題の概要

本記事では、配列の中から出現回数が2回以上の要素をすべて見つける問題を解説します。

例として、次の配列を考えてみましょう。

{1, 5, 2, 5, 3, 1, 5, 2, 7}

この場合、1は2回、5は3回、2は2回出現しており、それ以外の要素(3と7)はそれぞれ1回しか登場しません。したがって、求める出力は {1, 5, 2} となります。

アルゴリズム

この問題は、ハッシュマップ(連想配列)を利用することで効率的に解けます。基本的な流れは以下の通りです。

moreFreq(arr, n)

Begin
    キーと値がともに int 型のマップを定義する
    配列 arr の各要素 e に対して、以下を実行する
        マップ内の該当キーの値(出現回数)を1増やす
    繰り返し終了
    各キーについて値が1より大きい場合、そのキーを出力する
End

まず配列を一度走査して各要素の出現回数をマップに記録し、その後マップを走査して出現回数が1を超えるキーだけを出力します。

C++による実装例

以下は、C++ の std::map を使った具体的な実装です。

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

void moreFreq(int arr[], int n){
    map<int, int> freq_map;
    for(int i = 0; i<n; i++){
        freq_map[arr[i]]++; // 出現回数をカウントアップ
    }
    for (auto it = freq_map.begin(); it != freq_map.end(); it++) {
        if (it->second > 1)
            cout << it->first << " ";
    }
}

int main() {
    int arr[] = {1, 5, 2, 5, 3, 1, 5, 2, 7};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Frequency more than one: ";
    moreFreq(arr, n);
}

実行結果

Frequency more than one: 1 2 5

計算量について

std::map は内部で平衡二分探索木(赤黒木)を使用しているため、挿入や検索の計算量は O(log n) です。そのため、全体の時間計算量は O(n log n)、空間計算量は O(n) となります。

なお、順序が不要であれば unordered_map を使うことで、平均 O(1) でのアクセスが可能になり、全体の計算量を O(n) まで抑えられます。用途に応じて使い分けるとよいでしょう。

  1. C++で3つ以上の数値(または配列)の最大公約数(GCD)を求める方法

    本記事では、3つ以上の数値の最大公約数(GCD)をC++で求める方法を解説します。2つの数値のGCDを求めるのは簡単ですが、3つ以上の数値を扱う場合はGCDの結合法則を利用します。例えば、{w, x, y, z} のGCDを求めたい場合、以下のように段階的に計算します。まず {gcd(w, x), y, z} を計算次に {gcd(gcd(w, x), y), z) を計算最後に {gcd(gcd(gcd(w, x), y), z)} を計算この手法を配列に適用すれば、任意の個数の数値に対してGCDを簡単に求めることができます。アルゴリズムgcd(a, b)begin    

  2. 【Java】2つ以上の数値や配列の最大公約数(GCD)を求めるプログラム

    最大公約数(GCD:Greatest Common Divisor)とは、複数の整数に共通する約数の中で最も大きいもののことです。この記事では、2つ以上の数値(配列の全要素)からGCDを求めるJavaプログラムを、サンプルコードと実行結果とあわせて解説します。サンプルコードpublic class Demo{ static int gcd_of_nums(int val_1, int val_2){ if (val_1 == 0) return val_2; return gcd_of_nums(val_2 % val_1, va