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

C++で0・1・2のみの配列をソートする方法|DNF(オランダ国旗)アルゴリズムを解説

0、1、2 のみで構成された配列が与えられたとき、すべての「0」を先頭に、「1」をその次に、「2」を末尾に配置するように要素を並べ替えることを考えます。このとき、追加のメモリを使用せずに配列をインプレース(in-place)でソートする必要があります。

この問題は、DNF(Dutch National Flag:オランダ国旗)ソートアルゴリズムを使うことで効率的に解くことができます。

入出力の例

例1

入力:

arr[ ] = {2, 0, 0, 1, 2, 1}

出力:

0 0 1 1 2 2

説明: DNFソートアルゴリズムを用いて0・1・2を含む配列を並べ替えると、{0, 0, 1, 1, 2, 2} の順に出力されます。

例2

入力:

arr[ ] = {0, 1, 1, 2, 1, 1, 0}

出力:

0 0 1 1 1 1 2

説明: 同じくDNFソートアルゴリズムによって、{0, 0, 1, 1, 1, 1, 2} の順に並べ替えられます。

この問題のアプローチ

0・1・2 のみからなる配列に対しては、DNFソートアルゴリズムを適用します。

DNFソートアルゴリズムとは: 3つのポインタを使いながら配列を走査し、必要な要素どうしを交換していくアルゴリズムです。手順は以下の通りです。

  • 配列の先頭に low ポインタ、末尾に high ポインタを配置します。

  • 配列の中間位置を基準に mid ポインタを作成し、配列の先頭から末尾まで走査させます。

  • mid ポインタが指す要素が「0」の場合:low ポインタが指す要素と交換し、low と mid を両方とも1つ進めます。

  • mid ポインタが指す要素が「2」の場合:high ポインタが指す要素と交換し、high を1つ戻します。

  • mid ポインタが指す要素が「1」の場合:その場に正しい要素があるため、mid だけを1つ進めます。

この処理を mid ポインタが high ポインタを追い越すまで繰り返すことで、O(n) の計算量・定数メモリで配列をソートできます。

C++による実装例

#include<iostream>
using namespace std;
void dnfsort(int a[], int n){
   int low= 0;
   int high= n-1;
   int mid=0;
   while(mid<=high){
      if(a[mid]==0){
         swap(a[mid],a[low]);
         mid++;
         low++;
      }
      if(a[mid]==1){
         mid++;
      }
      if(a[mid]==2){
         swap(a[mid],a[high]);
         high--;
      }
   }
}
int main(){
   int a[]= {1,0,0,2,1,1,0,0,1};
   int n= sizeof(a)/sizeof(int);
   dnfsort(a,n);
   for(int i=0;i<n;i++){
      cout<<a[i]<<" ";
   }
   return 0;
}

実行結果

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

0 0 0 0 1 1 1 1 2

このように、DNFソートアルゴリズムを利用すれば、0・1・2 のみで構成された配列をたった1回の走査でインプレースに並べ替えることができます。

  1. C++で配列を使って数値の平均を計算する方法【初心者向け解説】

    数値の平均値とは、すべての数値を合計し、その合計を数値の個数で割ることで求められます。これは統計やプログラミングの基礎となる重要な計算の一つです。平均の計算例具体的な例を見てみましょう。以下の5つの数値の平均を求める場合を考えます。平均を求める対象の数値:10, 5, 32, 4, 9 数値の合計 = 60 数値の平均 = 60 ÷ 5 = 12配列を使用した平均計算プログラムそれでは、C++で配列を使用して数値の平均を計算するプログラムを見ていきましょう。サンプルコード#include <iostream> using namespace std; int main() {

  2. Javaで0・1・2の配列をソートする方法|DNF(オランダ国旗)アルゴリズムの実装

    問題の概要 0、1、2 のみで構成された配列が与えられ、すべての「0」を先頭に、「1」を中間に、「2」を最後に配置するように並べ替えます。このとき、追加の配列を使用せずインプレース(in-place)でソートする必要があります。 この問題は、DNF(Dutch National Flag:オランダ国旗)ソートアルゴリズムを用いることで効率的に解けます。このアルゴリズムは、計算機科学者エドガー・W・ダイクストラが提唱した「オランダ国旗問題」に由来する古典的な手法で、3種類の値(ここでは 0・1・2)をたった1回の走査で整列できるのが特徴です。 入力例 1 arr[ ] = {2, 0, 0,