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

C++で行列内のすべての要素が同一である行の数を数える方法

整数で構成される行列が与えられたとき、すべての要素が同一である行が何行あるかを求めるのが、この記事のテーマです。

例として、次のような 4×5 の行列を考えてみましょう。

15131
11111
53235
77777

この場合の答えは 2 です。1行目(すべてが 1)と3行目(すべてが 7)は、同一の要素のみで構成されているためです。

それでは、具体的な例で確認していきましょう。

入出力の例

例1

入力:

matrix =
    [ 1 1 1 1 ]
    [ 2 3 2 7 ]
    [ 3 3 3 3 ]

出力: 同一要素で構成される行の数 − 2

説明: 0行目はすべて 1、2行目はすべて 3 で構成されているため、該当する行は 2 行です。

例2

入力:

matrix =
    [ 1 2 3 4 ]
    [ 1 2 3 4 ]
    [ 1 2 3 4 ]

出力: 同一要素で構成される行の数 − 0

説明: どの行にも異なる要素が含まれているため、該当する行は 1 行もありません。

プログラムで使用するアプローチ

ここでは、行列を vector<vector<int>> として扱います。各行に対して set<int> を作成し、その行の要素をすべてセットに挿入していきます。set は重複する要素を持たないため、最終的にセットのサイズが 1 であれば、その行は同一の要素のみで構成されていると判断できます。

  • 行列を vector<vector<int>> matrix として宣言し、初期化します。
  • matrix.size() を使って行数を取得します。
  • 関数 same_rows(vector<vector<int>> matrix, int size) は、行列とそのサイズを受け取り、同一要素で構成される行の数を返します。
  • カウント用の変数を初期値 0 で用意します。
  • for ループで i = 0 から i = size まで行列を走査します。
  • 各行について、j = 0 から j < matrix[i].size() まで要素を走査します。
  • 現在の行の要素を格納するための set<int> set_row を用意します。
  • set_row.insert(matrix[i][j]) で、現在の行の要素をセットに追加していきます。
  • 走査終了後、set_row のサイズを確認します。サイズが 1 であれば、その行は同一要素のみで構成されているため、カウントを増やします。
  • すべての行の走査が終わったら、カウントを最終結果として返します。

サンプルコード

#include <bits/stdc++.h>
using namespace std;

int same_rows(vector<vector<int>> matrix, int size){
    int count = 0;
    for (int i = 0; i < size; i++){
        set<int> set_row;
        for (int j = 0; j < matrix[i].size(); j++){
            set_row.insert(matrix[i][j]);
        }
        if (set_row.size() == 1){
            count++;
        }
    }
    return count;
}

int main(){
    vector<vector<int>> matrix = {
        { 2, 2, 2, 2 },
        { 5, 5, 5, 5 },
        { 2, 2, 2, 2 },
        { 5, 5, 5, 5 }
    };
    int size = matrix.size();
    cout << "Count of rows in a matrix that consist of same element are: "
         << same_rows(matrix, size);
    return 0;
}

実行結果

上記のコードを実行すると、次の出力が得られます。

Count of rows in a matrix that consist of same element are: 4

この例では、4 つの行すべてが同一の要素のみで構成されているため、結果は 4 となります。

計算量と補足

行数を N、列数を M とすると、このアルゴリズムの時間計算量は O(N × M)、空間計算量は各行ごとにセットを保持するため O(M) となります。

なお、追加メモリを使いたくない場合は、set を使わずに「各行の先頭要素とそれ以外の要素を順番に比較する」方法でも判定できます。この場合、空間計算量は O(1) に抑えられます。状況に応じて使い分けるとよいでしょう。

  1. C++で配列内の各要素のサーパッサー(Surpasser)の数を求めるアルゴリズム

    ある配列Aが与えられたとき、各要素の「サーパッサー(surpasser)」の数を求める問題を考えてみましょう。サーパッサーとは、現在注目している要素よりも右側に存在する、その要素より大きい値のことです。 例えば、A = {2, 7, 5, 3, 0, 8, 1} という配列の場合、サーパッサーの数は {4, 1, 1, 1, 2, 0, 0} となります。これは、先頭の「2」の右側には「7・5・3・8」という4つの大きな値が存在するためです。その他の要素についても同じルールで数えていきます。 アルゴリズムの考え方 解法は非常にシンプルです。2重のループを使用し、外側のループで各要素を順に取り上

  2. 【C++】配列の全要素で剰余が等しくなる整数「k」を求めるプログラム

    本記事では、与えられた配列のすべての要素に対する剰余(mod)が同じ値になるような整数「k」を見つけるC++プログラムについて解説します。 問題の概要 例として、次のような配列が与えられたとします。 arr = {12, 22, 32} この場合、条件を満たすkの値は 1、2、5、10 となります。実際に確認してみると、これらの値で各要素を割った余りはすべて等しくなっています。 解法の考え方 まず、配列内の2つの値「x」と「y」(x > y)に注目します。両者の差を「difference」とすると、次の関係が成り立ちます。 (y + difference) % k = y % k この式