組み合わせの数

  1. 組み合わせの数
    1. 目的
      組み合わせの数を求めるアプレットのプログラムを作成します。計算そのものは単純なプログラムですが、ここでは、GUIによる数字の入力方法やボタン処理の方法が中心になります。
       ここでは、文字を表示する Labelクラス、文字を入力したり編集できる、TextField クラス、ボタンを押すと指定した関数(メソッド)を実行する Button クラス を紹介します。

    2. GUI部品の機能
      1. ラベルボックス
        文字を表示する機能です。図で、n,k の文字を表示しているのでラベルです。テキストボックスと異なり、文字の表示はできますが、変更や読みとりはできません。



      2. テキストボックス
         上の図で、5や3を表示している白い箱がテキストボックスです。実行時に箱をクリックして、値を変更することができます。入力された値は随時読みとることができます。

      3. ボタン
         この箱を押すことにより、指定した処理を実行することができます。ラベルと同様、ボタンに名前を付けることができます。



         テキストボックスの値を変更しこのボタンを押すと、新しい値の計算値を表示することができます。

    3. GUI部品のプログラム
      1. TextFieldクラス
        文字入力には、TextFieldクラスを利用します。
         private TextField nField = new TextField();
        で、文字入力フィールド(部品)nFieldを定義します。
         nField.setText("5");
        で、初期値を設定します。
         nField.setBounds(new Rectangle(60, 40, 60, 20));
        で箱の位置とサイズを指定します。(60, 40)が入力枠の左上の座標、(60,20)が幅と高さです。座標は、ウインドウの左上が原点です。x座標の数が増えると右方向に、y座標が増えると下方向に箱が移動します。
        このnFieldに「組み合わせの数:n」を入力します。
         同様に、「取り出す数:k」を入力する kField と、計算した組み合わせ数を表示する rField 用意します。

      2. ラベルクラス
         ラベルクラスは、文字列を表示する枠を提供するクラスです。TextFieldクラスと異なり、文字列の入力や編集はできません。"n" を表示するラベルは以下のように指定します。

         private Label label1 = new Label();
         label1.setText("n");
         label1.setBounds(new Rectangle(35, 40, 20, 20));

      3. ボタンクラス
        変換ボタン factbutton を用意します。ボタンはButton クラスから作成します。setLabel でボタンの名前を、setBounds でボタンの枠を指定します。
         private Button permbutton = new Button();
         permbutton.setLabel("階乗");
         permbutton.setBounds(new Rectangle(50, 100, 80, 20));

        ボタンの役目を、押したとき、対応する処理を実行することです。ボタン に対して、実行する関数 permbutton_actionPerformed(e) を次のように指定します。addActionListener()が、対応する関数を追加します。

         permbutton.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
          permbutton_actionPerformed(e); }
          });

      4. 部品の追加
         実際にアプレットのウインドウに部品を追加するには、add() を利用します。その前に、ここでは、部品の配置位置をマニュアルで指定しますから、次のように自動配置を無効にします。

         this.setLayout(null);

        次に、ボタンや文字入力部品を配置します。
          this.add(factbutton, null);
         this.add(kField, null);
         this.add(permbutton, null);
         this.add(rField, null);
         this.add(nField, null);
         this.add(label1, null);
         this.add(label2, null);

    4. 文字の読み出し・変更と型変換
       文字入力部品 nField から入力された文字を取り出すには

       nField.getText()

      を利用します。これは String型の文字列を返します。入力される値は文字型ですから、計算をするには、数値型(ここでは double)に変換する必要があります。このため、

       int nnum=Integer.parseInt(nField.getText());

      を実行します。parseは文字を「解析」する意味です。文字列stを整数に変換する場合は、Integer.parseInt(st); とします。ここでは st はnField.getText() で取り出します。

       逆に、int型の小数xを小数型の文字にs2変換するには
       String st=Double.toString(x);
      とします。この文字を rField に表示するには
       rField.setText(st);
      です。

    5. 階乗の計算
       階乗の計算は、関数 fact で行います。これは、1から 引数 num までの値を変数 rs に掛け算します。rs の初期値は1にします。 for (int i=1;i<=num;i++) { } の意味は、変数 i の値を1からnumまで、i を1づつ増しながら { } の中を実行します。記述の形式は 言語C と全く同じです。
       return rs は rs の値を関数の値として、戻る(関数の実行を終了する)ことでしたね。
        int fact(int num){
          int rs=1;
          for (int i=1;i<=num;i++){
            rs = rs*i;
          }
          return rs;
        }

    6. 順列の数の計算
       組み合わせの数を計算する関数 permbutton_actionPerformed() は次のようになります。先頭で、入力枠から k と r の値を変数 nnum と knum に読み出します。
      次に、fact() を利用して順列の値を計算し、rField に表示します。

        void permbutton_actionPerformed(ActionEvent e) {
              int rs=1;
              int nnum=Integer.parseInt(nField.getText());
              int knum=Integer.parseInt(kField.getText());
      
              rField.setText(Integer.toString(fact(nnum)/fact(nnum-knum)));
        }

  2. プログラム

    1. 画面の初期設定
       アプレットは、起動されるとウインドウを作成し、画面を構成するため、init() 関数を呼び出します。ここで、部品を生成・初期化します。

    2. 処理の流れ
       順列ボタンを押すと permbutton_actionPerformed が呼び出されるます。この関数で、順列の値 P = n!/ (n-k) !
      を計算します。

    3. ソース
       
      import java.awt.*;
      import java.awt.event.*;
      import java.applet.*;
      
      public class PermNum extends Applet {
        private boolean isStandalone = false;
        private TextField nField = new TextField();
        private TextField kField = new TextField();
        private Button permbutton = new Button();
        private TextField rField = new TextField();
        private Label label1 = new Label();
        private Label label2 = new Label();
      
      
        //コンポーネントの初期化
        public void init()  {
              nField.setText("5");
              nField.setBounds(new Rectangle(60, 40, 60, 20));
              this.setLayout(null);
              kField.setBounds(new Rectangle(200, 40, 60, 20));
              kField.setText("3");
              permbutton.setLabel("順列");
              permbutton.setBounds(new Rectangle(50, 100, 80, 20));
              permbutton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(ActionEvent e) {
                      permbutton_actionPerformed(e);
                }
              });
      
              rField.setText("0");
              rField.setBounds(new Rectangle(100, 150, 80, 20));
              label1.setText("n");
              label1.setBounds(new Rectangle(35, 40, 20, 20));
              label2.setText("k");
              label2.setBounds(new Rectangle(160, 40, 20, 20));
              this.add(permbutton, null);
              this.add(kField, null);
              this.add(rField, null);
              this.add(nField, null);
              this.add(label1, null);
              this.add(label2, null);
        }
      
      
        int fact(int num){
              int rs=1;
              for (int i=1;i<=num;i++){
                rs = rs*i;
              }
              return rs;
        }
      
        void permbutton_actionPerformed(ActionEvent e) {
              int rs=1;
              int nnum=Integer.parseInt(nField.getText());
              int knum=Integer.parseInt(kField.getText());
      
              rField.setText(Integer.toString(fact(nnum)/fact(nnum-knum)));
        }
      }

    4. 実行
       n と k をクリックして値を変更し、「順列」ボタンを押すと、順列の値 nPk が表示されます。



  3. 演習
     
    1. 演習1
      プログラムのソースをPermNum.javaの名前でファイルに保存し、コンパイルしクラスファイルを生成します。このクラスファイルを実行する htm ファイルを生成し、ブラウザで実行します。
       n=6、k=3 の場合の計算値と理論値を比較して下さい。

    2. 演習2
      「組み合わせ」の数を  n!/ ((n-r) ! ・ r !) を計算するボタンを追加してください。

      先頭でボタン combbutton を作成します(new)。
       メソッド init で、combbutton のラベル(setLabel)と位置(setBounds)を指定します。
        ボタンの位置は、permbuttonの横にします。
       combbuttonを押したら、combbutton_actionPerformed(e); を呼び出す設定をします(addActionListener)。

      void combbutton_actionPerformed(ActionEvent e) メソッドを作成します。