PHP range関数を使って階乗と重複組み合わせを計算
2018/01/07
「乱数発生器」
http://s-giken.info/random/random.php
乱数発生器という Webアプリを作りました。
「乱数発生器」は見た目は非常にシンプルで、というか、実際中身の処理も非常に簡単なものなのですが(処理そのものは数行ですから)、処理を実行する前に細かく入力チェックを行っています。
その中で、任意の文字列から重複せずに生成できる文字列の件数と、生成の要求の件数を比較する、というチェックがあります。
具体的には、「ab」の 2文字から重複せずに生成できる文字列は「aa」「ab」「ba」「bb」の 4種類しかありません。
ですが、「ab」の文字列から 6件のランダム文字列が欲しいという条件入力があった場合は生成できませんので、それは入力エラーとして処理する必要があるわけです。
その際、指定の文字列から重複組み合わせの計算を行い、何件まで生成が可能なのか、を計算する必要があるわけですが、久しぶりに重複組み合わせの考え方を思い出す必要があり、ちょっと大変でした。
また、重複組み合わせを計算するには、階乗を計算する必要があり、これをプログラムで記述する必要が出てきます。
階乗については、下記のサイトに練習問題として提示されており、回答として for文でぐるぐる回す方法が提示されています。
http://torasukenote.blog120.fc2.com/blog-entry-49.html
range関数で乱数を生成する
私は、こちらのやり方を参考にしつつ rangeという関数を使って処理を作ってみました。
for文が複数出てくると、プログラムを組んでいるときはよくても、後から読むときが大変なのでそれを軽減することを目的にこのような処理を作ってみました。
また、rangeという関数は、非常に便利な関数で、for分を使わずにもいろいろな処理を簡潔に書けるのではないか、と思いました。
上記の URLの練習問題と同じことを下記の処理で再現できます。
1 2 3 4 5 6 7 8 |
for ( $i = 1; $i <= 10; $i++ ) { $kumiawase = 1; $num = range ( $i, 1 ); foreach ( $num as $val ) { $kumiawase *= $val; } echo $i . "! = " . $kumiawase . "<br />"; } |
また、実際のプログラムに組み込んでいる重複組み合わせの数を取得する関数は下記のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 重複組み合わせの計算(n H r) function r_combination ( $mojisuu, $keta ) { $num1 = range ( ( $mojisuu + $keta - 1 ), 1 ); $num2 = range ( $keta, 1 ); $num3 = range ( ( $mojisuu -1 ), 1 ); $kumiawase = 1; foreach ( $num1 as $val ) { $kumiawase *= $val; } foreach ( $num2 as $val ) { $kumiawase /= $val; } foreach ( $num3 as $val ) { $kumiawase /= $val; } return $kumiawase; } |
ちなみに、ここでは関数にしていますが、実際のプログラムでは関数にはしていません!
なぜなら、これまで十数年プログラムを組んできましたが、重複組み合わせが必要になったのはこれが初めてだからですね。
ここで関数を作っても、もう今後も使う機会はないでしょう。という判断ですね。
乱数発生器(パスワード生成サービス) Ver.2 登場!
乱数発生器(パスワード生成サービス)ですが、2017年06月17日に、処理内容を見直し、高速化してバージョン 2としてリニューアル新登場!
乱数生成の処理と、重複チェックの処理を見直して、数十万件の乱数生成が数秒でできてしまいます!
新しいバージョンも是非とも試して見てください。
乱数発生器(パスワード生成サービス) Ver.2
https://s-giken.info/random/random.php
また、解説記事を下記に書いていますので、あわせて参考にしてください。
乱数発生器(パスワード生成サービス)がバージョンアップで高速化!
また、JavaScriptを利用して、入力エリアの横に「パスワードを生成する」ボタンを追加する機能について下記に記事を書いています。あわせてご覧ください。
JavaScriptで「パスワードの生成」ボタンを追加する処理サンプル
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
PHPのデバッグで使う print_r、var_dump、var_exportの動作の違い
PHPのデバッグ等で変数や配列の中身を確認するために使用する関数print_r、var_dump、var_exportの動作の違い、仕様の違いについて確認した。var_exportがオススメ。
-
-
数値文字参照コード変換ツール(HTML特殊文字コード変換ツール)
テキストを数値文字参照コード(特殊文字コード)に変換するツール。テキストを数値文字参照コードに簡単変換。数値文字参照、文字実体参照、特殊文字などの違いも解説。
-
-
フォルダを指定してファイルのパーミッションを変更するプログラム
フォームからフォルダ、パーミッションを指定しパーミッションを変更するサンプルプログラムの解説です。
-
-
ECCUBEでアップロードできない。upload_max_filesizeを設定する場所
テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。
-
-
配列の値をテキスト表示する際に「、」でつなげるときの処理方法の一例
配列の値を「、」でつないで出力する際、単純にforeachで繰り返し処理をすると「イヌ、サル、キジ、」となるが文字列最後の「、」を出力しない方法を3つ解説している。
-
-
PHPのソースで見慣れない記号が出てきた・アロー演算子(->)、ダブルアロー演算子(=>)
PHPのプログラムソースには見慣れない記号が出てきます。その意味や調べ方です。
-
-
CentOS6、7のPHPを5.3から5.6、7.0、7.1にバージョンアップする手順の解説
CentOS6系、7系のPHPバージョンを5.3から5.6、7.0、7.1にアップする作業手順と解説。yum updateコマンドを使い作業時間は約10分。コマンドの解説や引数の意味なども解説しているので役に立つはず。
-
-
PHPのcURLでAPIやWebサイトへのアクセス方法。file_get_contentsとの比較
PHPからWebサイトにアクセスしてHTMLを取得、APIにアクセスして情報を取得する場合は、cURLがオススメ。file_get_contentsでも可能だがエラー制御に難がありトラブルのもとになる。
-
-
ECCUBEの問い合わせフォームに任意の値を引数として渡す方法
ECCUBEのお問い合わせフォームに値を固有の情報を送りそれに基づいて処理をする方法を解説。ボタンの設置、受け取り側のテンプレート、プログラムのサンプルソースを提供。
-
-
複数銘柄を指定して株価チャートを一覧するツール公開
入力銘柄の5日間、3か月間、6か月間、1年間、2年間の株価チャートを一覧表示しますのでチャートで売買判断をするのに最適です。