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

C++でスタックのポップ操作回数を数えて配列の各要素を取得する方法


数値の配列とスタックが与えられます。配列のすべての要素はスタック内に格納されており、各配列要素を取り出すために必要なポップ操作の回数を求めるのが目的です。

スタックには要素が降順で格納されており、最下部の要素が最大値、最上部(トップ)の要素が最小値となります。

入力例

Stack [ 7,6,2,1 ] array : 2,1,6,7

出力

Count of number of pop operations on stack to get each element of the array are: 3 1 0 0

説明

配列を先頭のインデックスから順に走査します。2 を取得するにはスタックを 3 回ポップする必要があるため、arr[0] は 3 になります。このとき最初の 2 回のポップで 7 と 6 も一緒に取り出されます。次に 1 を取得するには 1 回ポップするだけでよいので、arr[1] は 1 です。6 と 7 はすでにポップ済みのため、arr[2] = arr[3] = 0 となります。

別の入力例

Stack [ 3,2,1,1 ] array : 1,2,1,3

出力

Count of number of pop operations on stack to get each element of the array are: 3 0 1 0

説明

配列を先頭から順に走査します。最初の 1 を取得するにはスタックを 3 回ポップする必要があり、arr[0] は 3 です。このとき 3 と 2 も同時に取り出されます。次の 2 はすでにポップ済みなので arr[1] は 0。続く 1 を取得するにはさらに 1 回ポップが必要なため arr[2] は 1、最後の 3 はすでに取り出し済みなので arr[3] は 0 となります。

アルゴリズムの考え方

このアプローチでは、unordered_map<int, bool> 型の変数 um を使い、ある要素がすでにポップ済みかどうかを判定します。要素をポップするたびに um に登録し、対象の要素がすでに登録済みならポップ回数は 0 として扱います。未登録の場合は、目的の要素が見つかるまでポップを繰り返してカウントを増やしていきます。

  • 整数型の配列 arr[] を用意します。
  • 要素を格納するための stack<int> 型の stck を用意します。
  • 要素を降順でスタックにプッシュします。
  • 関数 pop_operations(stack<int>& stck, int arr[], int elements) は、配列の各要素を取得するために必要なポップ操作の回数を計算して出力します。
  • 初期カウントを 0 に設定します。
  • ポップ操作中に出現した一意な数値を記録する unordered_map<int, bool> 型の um を用意します。
  • for ループで配列を先頭から走査します。
  • temp = arr[i] として現在の対象要素を取得します。
  • temp がすでに um に存在する(=ポップ済みの)場合は、ポップ操作不要として 0 を出力します。
  • そうでない場合は、temp が見つかるまでスタックをポップし続け、ポップした各要素を um に true として記録しながらカウントを増やします。
  • while ループを抜けた時点でカウントを出力します。
  • これにより、配列の各要素に対応するポップ操作の回数が出力されます。

コード例

#include <bits/stdc++.h>
using namespace std;
void pop_operations(stack<int>& stck, int arr[], int elements){
    int count = 0;
    unordered_map<int, bool> um;
    cout<<"Count of number of pop operations on stack to get each element of the array are: ";
    for (int i = 0; i < elements; ++i){
        int temp = arr[i];
        if (um.find(temp) != um.end())
        { cout << "0 "; }
        else{
            count = 0;
            while (stck.top() != temp){
                um[stck.top()] = true;
                stck.pop();
                count++;
            }
            stck.pop();
            count++;
            cout<<count<<" ";
        }
    }
}
int main(){
    int elements = 4;
    int arr[] = { 2, 1, 6, 7};
    stack<int> stck;
    stck.push(1);
    stck.push(2);
    stck.push(6);
    stck.push(7);
    pop_operations(stck, arr, elements);
    return 0;
}

出力

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

Count of number of pop operations on stack to get each element of the array are: 3 1 0 0
  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++ STLのstd::arrayで使えるget()関数の使い方を徹底解説

    この記事では、C++ STLのstd::arrayコンテナに用意されているget()関数について詳しく解説します。この関数は、配列コンテナ内のi番目の要素を取得するために使用される便利な非メンバ関数です。 構文 get<i> array_name get()関数は、2つの必須パラメータを受け取ります。 1つ目はインデックスパラメータで、配列のi番目の位置を指定します。ここにはテンプレート引数として整数の定数を渡します。 2つ目は配列名(array_name)で、実際に要素を取り出す対象となる配列そのものです。 この関数は、指定されたi番目の要素への参照を返します。 なお、get()