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
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
ECCUBEでアップロードできない。upload_max_filesizeを設定する場所
テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。
-
-
Smartyの修飾子regex_replaceで正規表現の後方参照・PHPではpreg_replace
ECCUBEで使われているSmartyで文字列を正規表現で置換し後方参照で値を利用する装飾子regex_replaceの解説です。細かな条件がありますので注意が必要です。
-
-
PHP画面が真っ白 header(“Location: $url”);
PHPの開発で header(“Location: $url”);を使うと画面が真っ白になる不具合が出る場合もあります。
-
-
ECCUBEのポイント設定、ポイント付与率を一括で変更する方法解説
ECCUBEの商品個別に設定してあるポイントを一括で変更する方法を解説。ECCUBEには商品個別のポイントを一括して変更する機能がありません。SQLを作成して一括置換!
-
-
連想配列のキーも値もまとめてhtmlspecialchars()でサニタイズする関数の作成解説
PHPの配列・連想配列のキーと値をまとめてhtmlspecialchars()関数でサニタイズ(無害化、無毒化)を行う関数を作成。連想配列のキーはarray_map()関数でのサニタイズは無理。
-
-
ECCUBEでカード決済NGの受注情報をマイページ購入履歴に表示しない方法解説
ECCUBEでカード決済に失敗しても購入履歴一覧に注文情報(受注情報)が表示される問題への対処方法を解説。受注情報レコードの作成の流れとステイタスについても解説。
-
-
数値がMySQLのint(11)に保存できない!PHPの変数が本当にint型か確認!
PHPでintegerとdoubleが混在するような計算をする場合は要注意!計算結果が整数値であっても途中で使用する変数にdoubleの値が入っているときは計算結果がintegerではない場合があります。
-
-
WindowsのXAMPPのPHPではstrptimeは使用不可。代替はdate_parse_from_formatを使う
strptimeはWindowsのPHPには未実装。LinuxとMacで挙動が異なる。PHP8.1で非推奨になる。なので日付のチェックはdate_parse_from_formatを使おう。使い方を詳細解説。
-
-
PHPのデバッグで使う print_r、var_dump、var_exportの動作の違い
PHPのデバッグ等で変数や配列の中身を確認するために使用する関数print_r、var_dump、var_exportの動作の違い、仕様の違いについて確認した。var_exportがオススメ。
-
-
PHPのcURLでAPIやWebサイトへのアクセス方法。file_get_contentsとの比較
PHPからWebサイトにアクセスしてHTMLを取得、APIにアクセスして情報を取得する場合は、cURLがオススメ。file_get_contentsでも可能だがエラー制御に難がありトラブルのもとになる。