2019.06.24
同じ数の組み合わせ
同じ数の見つけ方
例えば、配列に格納されている値が、
{ 0、0、7、0、7 }
の場合、
0、7
の2種類の数字が配列に格納されているので、2が同じ数の組み合わせ数となります。
他の例で、配列に格納されている値が、
{ 3、3、6、2、1、3 }
の場合、
1、2、3、6
の4つの種類の数字が配列に格納されているので、4が同じ数の組み合わせ数となります。
ここで紹介するプログラムは配列の昇順ソート(降順でも良い)を使って同じ値を配列の中で連続に並べた後、配列の先頭から後方に向けて順番に値の変化を見ていき、値が変わった数を数えれば、その数が組み合わせの数となります。
{ 0、0、7、0、7 } ↓昇順ソート { 0、0、0、7、7 }
となり、0が3個、7が2個連続に並んだことが分かります。
{ 3、3、6、2、1、3 } ↓昇順ソート { 1、2、3、3、3、6 }
となり、1が1個、2が1個、3が3個、6が1個連続に並んだことが分かります。
{ 0、0、0、7、7 }の場合、{ 0、0、0、7、7 }のように先頭の"0"と4番目の"7"が、1つ前の値と違う箇所になります。この場合、2箇所違ったので2種類です。
{ 1、2、3、3、3、6 }の場合、{ 1、2、3、3、3、6 }のように先頭の"1"と2番目の"2"、3番目の"3"、6番目の"6"が1つ前の値と違う箇所になります。この場合、4箇所違ったので4種類です。
Javaソースコード
NumberCombo1.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088
import java.util.Arrays; public class NumberCombo1 { // 数の組み合わせ数を取得 public static int numberCombo( int[] ary ) { int nc; // 組み合わせ数 int prenum; // 1つ前の番号 int[] tempary; // 作業用の配列 // aryがnullなら0を戻す if ( null == ary ) return 0; // aryの数が0以下ならaryの数を戻す if ( 1 >= ary.length ) return ary.length; // 元の配列の順番を変えないように配列をコピー tempary = array_copy( ary ); // 昇順ソート Arrays.sort( tempary ); // 組み合わせの数の取得処理 // 組み合わせ数の初期値を代入 nc = 1; prenum = tempary[ 0 ]; // 処理本体 for ( int i = 1; i < tempary.length; ++ i ) { // 1つ前の値と一致しなければ if ( prenum != tempary[ i ] ) { // 組み合わせの数を増やす ++ nc; prenum = tempary[ i ]; } } // 結果を戻す return nc; } // 配列をコピー作成するメソッド private static int[] array_copy( int[] srcary ) { // 元の配列srcaryの要素数でint配列desaryを作成 int[] desary = new int[ srcary.length ]; // 配列desaryにsrcaryの値を代入 for ( int i = 0; i < srcary.length; ++ i ) { desary[ i ] = srcary[ i ]; } // 作成した配列desaryを戻す return desary; } // メイン public static void main( String[] args ) { // 組み合わせ数 int nc; // 配列aを宣言 int[] a; // 要素数10を設定 a = new int[ 10 ]; // 値を代入 a[ 0 ] = 0; a[ 1 ] = 5; a[ 2 ] = 5; a[ 3 ] = 1; a[ 4 ] = 3; a[ 5 ] = 0; a[ 6 ] = 5; a[ 7 ] = 2; a[ 8 ] = 6; a[ 9 ] = 7; // 組み合わせ数を取得 (0,1,2,3,5,6,7)の7種類 nc = numberCombo( a ); // 結果を表示 System.out.println( "同じ数の組み合わせ:" + nc ); } }
コンパイル ソースコードが「ANSI」の場合
C:\talavax\javasample>javac -encoding sjis NumberCombo1.java
コンパイル ソースコードが「UTF-8」の場合
C:\talavax\javasample>javac NumberCombo1.java
実行
C:\talavax\javasample>java NumberCombo1
実行結果
同じ数の組み合わせ:7
Javaソースコードの解説
ここから、ソースコードについて解説してきます。
003
public class NumberCombo1 {
クラス名を、NumberCombo1としています。
004 005 006
// 数の組み合わせ数を取得 public static int numberCombo( int[] ary ) {
007 008 009
int nc; // 組み合わせ数 int prenum; // 1つ前の番号 int[] tempary; // 作業用の配列
同じ数の組み合わせを取得するために使う変数を宣言しています。
011 012
// aryがnullなら0を戻す
if ( null == ary ) return 0;
014 015
// aryの数が0以下ならaryの数を戻す
if ( 1 >= ary.length ) return ary.length;
017 018
// 元の配列の順番を変えないように配列をコピー
tempary = array_copy( ary );
配列aryと同じ値を格納した配列temparyを作成します。ここでは、配列の値を並び替え(ソート)を利用して組み合わせを求めています。このメソッドの中で、配列aryをソートすると呼び出したメソッド側でもソートが行われた状態になるので、配列temparyを作成することで呼び出し側への影響を無くしています。
020 021
// 昇順ソート
Arrays.sort( tempary );
{ 0、5、5、1、3、0、5、2、6、7 }
を昇順ソートすると、
{ 0、0、1、2、3、5、5、5、6、7 }
となります。
023 024 025 026
// 組み合わせの数の取得処理 // 組み合わせ数の初期値を代入 nc = 1; prenum = tempary[ 0 ];
変数prenumの値が、組み合わせの1つ目ということを意味しています。
028 029
for ( int i = 1; i < tempary.length; ++ i ) {
ソースコードの15行目の処理で要素数が1以下の場合には、既にこのメソッドを抜けているので、この処理にたどり着いたときには配列temparyの要素数は2以上です。よって、2番目(i=1)から開始することができます。
030 031 032 033 034 035
// 1つ前の値と一致しなければ if ( prenum != tempary[ i ] ) { // 組み合わせの数を増やす ++ nc; prenum = tempary[ i ]; }
配列temparyの値tempary[i]と同じ値であれば、何も処理していません。
038 039
// 結果を戻す return nc;
組み合わせ数を格納した変数ncの値を戻します。
043 044 045
// 配列をコピー作成するメソッド private static int[] array_copy( int[] srcary ) {
046 047
// 元の配列srcaryの要素数でint配列desaryを作成 int[] desary = new int[ srcary.length ];
049 050 051 052
// 配列desaryにsrcaryの値を代入 for ( int i = 0; i < srcary.length; ++ i ) { desary[ i ] = srcary[ i ]; }
054 055
// 作成した配列desaryを戻す return desary;
059 060
// メイン public static void main( String[] args ) {
このmainメソッドからプログラムを実行します。
061 062
// 組み合わせ数 int nc;
同じ数の組み合わせ数を格納する変数ncを宣言しています、
064 065
// 配列aを宣言 int[] a;
067 068 069 070 071 072 073 074 075 076 077 078 079 080
// 要素数10を設定 a = new int[ 10 ]; // 値を代入 a[ 0 ] = 0; a[ 1 ] = 5; a[ 2 ] = 5; a[ 3 ] = 1; a[ 4 ] = 3; a[ 5 ] = 0; a[ 6 ] = 5; a[ 7 ] = 2; a[ 8 ] = 6; a[ 9 ] = 7;
082 083
// 組み合わせ数を取得 (0,1,2,3,5,6,7)の7種類
nc = numberCombo( a );
085 086
// 結果を表示 System.out.println( "同じ数の組み合わせ:" + nc );
結果を表示しています。
以上です。