ゆるゆるプログラミング

・同じ数の組み合わせ

ここでは、整数型の配列の中に、同じ値の数値が何種類あるか求める方法を紹介しています。

例えば、配列に格納されている値が、

 { 0、0、7、0、7 }

の場合、

  0、7

の2つの数字が配列に格納されているので、が同じ数の組み合わせ数となります。

他の例で、配列に格納されている値が、

 { 3、3、6、2、1、3 }

の場合、

  1、2、3、6

の4つの数字が配列に格納されているので、が同じ数の組み合わせ数となります。

ここから、Javaのソースコードを使って解説していきます。

NumberCombo1.java ← クリックしてダウンロードページに移動
001:    import java.util.Arrays;
002:    
003:    public class NumberCombo1 {
004:    	// 数の組み合わせ数を取得
005:    	public static int numberCombo( int[] ary )
006:    	{
007:    		int nc;		// 組み合わせ数
008:    		int prenum;	// 1つ前の番号
009:    		int[] tempary;	// 作業用の配列
010:    
011:    		// aryがnullなら0を戻す
012:    		if ( null == ary ) return 0;
013:    
014:    		// aryの数が0以下ならaryの数を戻す
015:    		if ( 1 >= ary.length ) return ary.length;
016:    
017:    		// 元の配列の順番を変えないように配列をコピー
018:    		tempary = array_copy( ary );
019:    
020:    		// 昇順ソート
021:    		Arrays.sort( tempary );
022:    
023:    		// 組み合わせの数の取得処理
024:    		// 組み合わせ数の初期値を代入
025:    		nc = 1;
026:    		prenum = tempary[ 0 ];
027:    		// 処理本体
028:    		for ( int i = 1; i < tempary.length; ++ i )
029:    		{
030:    			// 1つ前の値と一致しなければ
031:    			if ( prenum != tempary[ i ] ) {
032:    				// 組み合わせの数を増やす
033:    				++ nc;
034:    				prenum = tempary[ i ];
035:    			}
036:    		}
037:    
038:    		// 結果を戻す
039:    		return nc;
040:    	}
041:    
042:    
043:    	// 配列をコピー作成するメソッド
044:    	private static int[] array_copy( int[] srcary )
045:    	{
046:    		// 元の配列srcaryの要素数でint配列desaryを作成
047:    		int[] desary = new int[ srcary.length ];
048:    
049:    		// 配列desaryにsrcaryの値を代入
050:    		for ( int i = 0; i < srcary.length; ++ i ) {
051:    			desary[ i ] = srcary[ i ];
052:    		}
053:    
054:    		// 作成した配列desaryを戻す
055:    		return desary;
056:    	}
057:    
058:    
059:    	// メイン
060:    	public static void main( String[] args ) {
061:    		// 組み合わせ数
062:    		int nc;
063:    
064:    		// 配列aを宣言
065:    		int[] a;
066:    
067:    		// 要素数10を設定
068:    		a = new int[ 10 ];
069:    
070:    		// 値を代入
071:    		a[ 0 ] = 0;
072:    		a[ 1 ] = 5;
073:    		a[ 2 ] = 5;
074:    		a[ 3 ] = 1;
075:    		a[ 4 ] = 3;
076:    		a[ 5 ] = 0;
077:    		a[ 6 ] = 5;
078:    		a[ 7 ] = 2;
079:    		a[ 8 ] = 6;
080:    		a[ 9 ] = 7;
081:    
082:    		// 組み合わせ数を取得 (0,1,2,3,5,6,7)の7種類
083:    		nc = numberCombo( a );
084:    
085:    		// 結果を表示
086:    		System.out.println( "同じ数の組み合わせ:" + nc );
087:    	}
088:    } 

NumberCombo1.Javaの出力結果

同じ数の組み合わせ:7

int型配列に格納している値は、0,1,2,3,5,6,7の7種類です。

ここから、ソースコードについて解説してきます。

003:    public class NumberCombo1 {

クラス名を、NumberCombo1としています。

004:    	// 数の組み合わせ数を取得
005:    	public static int numberCombo( int[] ary )
006:    	{

public static int numberCombo( int[] ary )がint型配列に含まれる数値の種類を取得するメソッドです。

007:    		int nc;		// 組み合わせ数
008:    		int prenum;	// 1つ前の番号
009:    		int[] tempary;	// 作業用の配列

同じ数の組み合わせを取得するために使う変数を宣言しています。

011:    		// aryがnullなら0を戻す
012:    		if ( null == ary ) return 0;

int型配列aryが初期化されていない場合、0を戻しています。

014:    		// aryの数が0以下ならaryの数を戻す
015:    		if ( 1 >= ary.length ) return ary.length;

int型配列aryの要素数が1以下の場合は、その要素数を戻しています。要素数が1の場合、数の組み合わせは1で確定です。

017:    		// 元の配列の順番を変えないように配列をコピー
018:    		tempary = array_copy( ary );

配列aryと同じ値を格納した配列temparyを作成します。ここでは、配列の値を並び替え(ソート)を利用して組み合わせを求めています。このメソッドの中で、配列aryをソートすると呼び出したメソッド側でもソートが行われた状態になるので、配列temparyを作成することで呼び出し側への影響を無くしています。

配列のコピーメソッドarray_copyは、ソースコードの43行目から56秒目を参照してください。

020:    		// 昇順ソート
021:    		Arrays.sort( tempary );

配列temparyを昇順ソートします。これで、配列temparyの値が、小さい値から大きい値に並び替えられます。

また、ソートすることで同じ値が配列の中で連続して格納されます。

このソースコードの場合、配列temparyの値

 { 0、5、5、1、3、0、5、2、6、7 }

昇順ソートすると、

 { 0、0、1、2、3、5、5、5、6、7 }

となります。

023:    		// 組み合わせの数の取得処理
024:    		// 組み合わせ数の初期値を代入
025:    		nc = 1;
026:    		prenum = tempary[ 0 ];

組み合わせ数の初期値ncに1を代入します。そして、配列temparyの先頭(添え字 0)の値を変数prenumに代入しています。

変数prenumの値が、組み合わせの1つ目ということを意味しています。

028:    		for ( int i = 1; i < tempary.length; ++ i )
029:    		{

for文を、配列temparyの2番目(添え字 1)から配列の最後までのループを作成しています。

ソースコードの15行目の処理で要素数が1以下の場合には、既にこのメソッドを抜けているので、この処理にたどり着いたときには配列temparyの要素数は2以上です。よって、2番目(i=1)から開始することができます。

030:    			// 1つ前の値と一致しなければ
031:    			if ( prenum != tempary[ i ] ) {
032:    				// 組み合わせの数を増やす
033:    				++ nc;
034:    				prenum = tempary[ i ];
035:    			}

配列temparyの値tempary[i]とprenumが違う場合、組み合わせ数ncを1つ増やして(インクリメント)、変数prenumにtempary[i]を代入しています。

配列temparyの値tempary[i]と同じ値であれば、何も処理していません。

038:    		// 結果を戻す
039:    		return nc;

組み合わせ数を格納した変数ncの値を戻します。

043:    	// 配列をコピー作成するメソッド
044:    	private static int[] array_copy( int[] srcary )
045:    	{

private static int[] array_copy( int[] srcary )が配列をコピーするメソッドです。srcaryがコピー元の配列です。

046:    		// 元の配列srcaryの要素数でint配列desaryを作成
047:    		int[] desary = new int[ srcary.length ];

コピー元の配列srcaryの要素数(srcary.length)で、コピー先の配列desaryを初期化しています。

049:    		// 配列desaryにsrcaryの値を代入
050:    		for ( int i = 0; i < srcary.length; ++ i ) {
051:    			desary[ i ] = srcary[ i ];
052:    		}

for文を使って、コピー先の配列desaryの各要素に、コピー元の配列srcaryの値を代入にしています。

054:    		// 作成した配列desaryを戻す
055:    		return desary;

メソッドの最後に、配列desaryをreturn文で戻しています。

059:    	// メイン
060:    	public static void main( String[] args ) {

このmainメソッドからプログラムを実行します。

061:    		// 組み合わせ数
062:    		int nc;

同じ数の組み合わせ数を格納する変数ncを宣言しています、

064:    		// 配列aを宣言
065:    		int[] a;

複数の値を格納するint型配列aを宣言しています、

067:    		// 要素数10を設定
068:    		a = new int[ 10 ];
069:    
070:    		// 値を代入
071:    		a[ 0 ] = 0;
072:    		a[ 1 ] = 5;
073:    		a[ 2 ] = 5;
074:    		a[ 3 ] = 1;
075:    		a[ 4 ] = 3;
076:    		a[ 5 ] = 0;
077:    		a[ 6 ] = 5;
078:    		a[ 7 ] = 2;
079:    		a[ 8 ] = 6;
080:    		a[ 9 ] = 7;

ここでは、要素数10個で配列aを初期化して、値を格納しています。この配列要素数と値は任意です。いろいろ試してみてください。

082:    		// 組み合わせ数を取得 (0,1,2,3,5,6,7)の7種類
083:    		nc = numberCombo( a );

作成したnumberComboメソッドの引数に配列aを渡して、同じ数の組み合わせ数ncを取得しています。

085:    		// 結果を表示
086:    		System.out.println( "同じ数の組み合わせ:" + nc );

結果を表示しています。

■関連コンテンツ

配列のコピーを作る 配列のコピーを作る方法を解説
配列 同じ型の変数をまとめた配列について解説
for文 繰り返し処理に使用するfor文について解説

■新着情報

2019.09.13 長さの単位変換 1マイル、1フィートは何m?
2019.09.06 クイックソート 高速に配列に並び替える方法
2019.09.05 中央値(メディアン) 配列に格納されている値の中央値を求める
2019.09.05 最頻値 配列から出現回数が最も多い値の取得
2019.09.03 配列値の反転 配列の反転処理
2019.08.05 トランプの操作 トランプを操作するクラス

 

 

 

 

 

 

 

 

 

Topへ