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

C++で配列から最後に削除される要素の位置を求める方法

この記事では、サイズ N の整数型配列 arr[] と整数値 M が与えられたときに、配列から最後に削除される要素の位置を求めるアルゴリズムを解説します。

問題の概要

配列から要素を削除する際には、以下のルールに従って操作を行います。

  • 配列内の各要素 arr[i] について、arr[i] > M の場合はその値をいったん取り出し、arr[i] − M を配列の末尾へ追加します。
  • arr[i] ≤ M の場合は、その要素を配列から削除します。
  • この操作を、配列が空になるまで繰り返します。

具体例で問題を理解する

入力:

arr[] = {5, 4, 8}, M = 3

出力:

3

解説:

操作に従って値を削除していくと、
{5, 4, 8} → {4, 8, 2} → {8, 1, 2} → {1, 2, 5} → {2, 5} → {5} → {2} → 空の配列
となり、最後に削除される値は 8 です。その位置は 3 番目です。

解法アプローチ

この問題には、「最後に削除される値は、ceil(arr[i] / M) の値が最大となる要素である」という性質を利用したシンプルな解法があります。

ceil(arr[i] / M) は、その要素が配列から消えるまでに何回の操作を受けるかを表す切り上げ除算です。したがって、配列を一度走査し、ceil(arr[i] / M) が最大となる位置を記録すれば、最後に削除される要素の位置が分かります。

なお、最大値を持つ要素が複数存在する場合は、配列の中でより後方に位置する要素が最後に削除されます。実装では配列を後ろから前に向かって走査し、現在の最大値より厳密に大きい値が出現したときだけ位置を更新することで、この条件を自然に満たしています。

C++での実装例

以下は、本解法の動作を示すサンプルプログラムです。

#include <iostream>
using namespace std;
int findLastRemPos(int arr[], int n, int m){
    for (int i = 0; i < n; i++) {
        arr[i] = (arr[i] / m + (arr[i] % m != 0));
    }
    int lastRemPos = -1, largestVal = -1;
    for (int i = n - 1; i >= 0; i--) {
        if (largestVal < arr[i]) {
            largestVal = arr[i];
            lastRemPos = i;
        }
    }
    return lastRemPos + 1;
}
int main(){
    int arr[] = {5, 4, 8, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
    int m = 3;
    cout<<"The position of last removed element in the array is "<<findLastRemPos(arr, n, m);
    return 0;
}

実行結果

The position of last removed element in the array is 3

コードのポイント

  • 最初のループでは、arr[i] / m + (arr[i] % m != 0) という式で切り上げ除算 ceil(arr[i] / m) を計算し、各要素を「削除までに必要な操作回数」に変換しています。
  • 2番目のループでは、配列を末尾から先頭へ走査し、これまでの最大値を上回る値が見つかった場合にのみ位置を記録します。
  • 計算量は時間 O(N)、追加メモリ O(1) と非常に効率的で、大きな配列でも高速に動作します。
  1. C#でラムダ式を使って配列の最大要素を取得する方法

    C#では、LINQのMax()メソッドとラムダ式を組み合わせることで、配列の中から最大値を簡単に取得できます。この記事では、基本的な使い方をサンプルコード付きでわかりやすく解説します。1. 配列を宣言するまず、対象となる整数型の配列を宣言します。int[] arr = { 10, 90, 20, 19, 99, 57 };2. Max()メソッドとラムダ式で最大値を取得する配列から最大の要素を取得するには、System.Linq名前空間に含まれるMax()メソッドを使用します。ラムダ式を渡すことで、各要素に対して任意の変換処理(この例では絶対値の計算)を適用した上で最大値を求めることができます

  2. C#で配列内の最後に一致する要素を見つける方法(Array.LastIndexOf活用)

    C#で配列内から最後に一致する要素を検索するには、Array.LastIndexOf メソッドを使用します。このメソッドは、指定した要素が配列内に存在する場合はその最後のインデックスを返し、存在しない場合は -1 を返します。対象となる配列ここでは、次のような整数型配列を例に考えます。int[] val = { 97, 45, 76, 21, 89, 45 };Array.LastIndexOfメソッドの使い方この配列の中には「45」が2つ含まれています。仮に、要素「45」が最後に出現する位置(インデックス)を調べたい場合は、次のように Array.LastIndexOf() メソッドを呼び出