2018/04/01 ブログのテーマをcocoonに変更しました。
スポンサーリンク

アナグラム全パターン作成する方法

スポンサーリンク

以前Pythonでアナグラム解析をする記事を書かせて頂きました。

【Python】超簡単にアナグラム解析
追記(2017/06/09):ページ内でアナグラム作成を出来るようにしましたー アナグラム作成はこちらから。 プログラムの説明は↓から そもそもアナグラムとは? アナグラム(anagram)とは、言葉遊びの一つで...

反響も良く、アナグラムの結果を全通り見れるサイトも見受けられなかったので、作ってみました~

↓こちらのリンクからアナグラムを作成出来ます。

アナグラム全パターン作成
アナグラムの全パターン(順列)を作成・出力をします。 文字が多すぎると処理に時間がかかるので、8文字までとします。 (8文字だと40320通り出力されます。) アナグラム全パターン作成の解説記事を書きました。 こちらもよろしくお願いします。

作成したプログラム

サイトに埋め込む必要があった為、JavaScriptで書きました。

コピペすれば動いちゃいます(笑)

<p>アナグラムの順列(全パターン)を生成・出力をします。</p>
<p>文字が多すぎると処理に時間がかかるので、8文字までとします。
<span style="font-size: 10px;">(8文字だと40320通り出力されます。)</span></p>
<form name="yes_anagram"><input type="text" name="dummy" style="display: none;" />
        <input type="text" name="textbox" /><br />
<button type="button" onclick="anagram();">作成</button></form>
<div class="sp-primary" id="hogehoge">結果</div>
<div>
  <script>
	function anagram(){
	  var msg = yes_anagram.textbox.value;
	  // 文字列を一文字ずつ分割
	  var list = msg.split('');
	  //文字が入力されていない場合
	  if (list.length == 0){
		alert("文字を入力してください");
		return;
	  }
	  //文字が8文字以上の場合
	  if (list.length > 8){
		alert("8文字まででお願いします");
		return;
	  }
	  //順列生成
	  var beforeTextArr = make_anagram(list);
	  //文字列の挿入
	  var afterText = '';
	  for(var i = 0; i < beforeTextArr.length; i++) {
		afterText += "[" + beforeTextArr[i] + "] ";
	  }
	  //テキストの挿入
	  document.getElementById('hogehoge').innerHTML = afterText ;
	}
	function make_anagram( list ){
	  if( list.length === 0 ){
		return null;
	  }
	  if( list.length === 1 ){
		return  [[ list[0] ]] ;
	  }
	  var result = [], head, copyList;
	  for( var i = 0 , n = list.length; i<n ; i++ ){
		//配列のコピー
		copyList = list.slice(0);
		//i番目の配列を抜きだす
		head = copyList.splice( i,1 );
		//再起処理
		newList = make_anagram( copyList );
		for( var j = 0 , m = newList.length ; j<m ; j++ ){
		  newList[j].unshift( head[0] );
		  result.push( newList[j] );
		}   
	  }
	  return result;
	}
      </script>
  </div>

 

解説

フォームの作成

フォームはHTMLで作成をしています。

フォームが2つありますが、1つはダミーのフォームです。Enterでフォームを送信させない為です。

<p>アナグラムの順列(全パターン)を生成・出力をします。</p>
<p>文字が多すぎると処理に時間がかかるので、8文字までとします。
<span style="font-size: 10px;">(8文字だと40320通り出力されます。)</span></p>
<form name="yes_anagram"><input type="text" name="dummy" style="display: none;" />
    <input type="text" name="textbox" /><br />
<button type="button" onclick="anagram();">作成</button></form>

 

 

ここをJavaScript側から要素の中身を変更します。

<div class="sp-primary" id="hogehoge">結果</div>

 

文字列の分割 挿入

テキストボックスから文字を取得し、1文字づつに分割して配列に入れます。

ここで、8文字以上or0文字のとき警告文を出します。

function anagram(){
          var msg = yes_anagram.textbox.value;
          // 文字列を一文字ずつ分割
          var list = msg.split('');
          //文字が入力されていない場合
          if (list.length == 0){
            alert("文字を入力してください");
            return;
          }
          //文字が8文字以上の場合
          if (list.length > 8){
            alert("8文字まででお願いします");
            return;
          }

 

順列を作成するmake_anagram()からアナグラムの配列を取得し、[   ]をつけて先ほど作ったHTML要素に挿入します。

//順列生成
          var beforeTextArr = make_anagram(list);
          //文字列の挿入
          var afterText = '';
          for(var i = 0; i < beforeTextArr.length; i++) {
            afterText += "[" + beforeTextArr[i] + "] ";
          }
          //テキストの挿入
          document.getElementById('hogehoge').innerHTML = afterText ;
        }

 

順列

こちらの関数を使い順列を求めます。

配列の頭を変えて全てのパターンを再起処理を使い総当たりします。

文字列 [m,i,x]の場合
[m],[i,x] → [m],[i],[x], [m],[x],[i]

[i],[m,x] → [i],[m],[x], [i],[x],[m]

[x],[m,i] → [x],[m],[i], [x],[i],[m]

function make_anagram( list ){
          if( list.length === 0 ){
            return null;
          }
          if( list.length === 1 ){
            return  [[ list[0] ]] ;
          }
          var result = [], head, copyList;
          for( var i = 0 , n = list.length; i<n ; i++ ){
            //配列のコピー
            copyList = list.slice(0);
            //i番目の配列を抜きだす
            head = copyList.splice( i,1 );
            //再起処理
            newList = make_anagram( copyList );
            for( var j = 0 , m = newList.length ; j<m ; j++ ){
              newList[j].unshift( head[0] );
              result.push( newList[j] );
            }   
          }
          return result;
        }

 

感想

今回はサイトに埋め込む関係上、JavaScriptで書きましたが、Pythonと比べると大変でした。先に簡単な方を知ってしまったから......(小声)

なんでJavaScriptでは標準で順列を作成するオブジェクトがないのかなぁ......

結果. Pythonは神

余談

メンバーのオサダ君が僕に触発され、JavaScriptを学んでいるようです。

初心者目線でとてもわかりやすいと思うので、興味のある方は是非!!(僕も勉強させてもらってます)

超初心者向け!!JavaScriptも一緒に学ぼう。Part.1
さぁ、オーカワに触発されPC言語について学び始めたオサダです。 今回は超初心者向けJavaScript。比較的簡単な言語ながら開発されてから使われ続けてる言語である(という評価が多いようです)。 htmlはマークアップ言語だと、前回のh...
超初心者向け!!JavaScriptも一緒に学ぼう。Part.2
前回の続きです。Part.1はこちら。 前回学んだことを(めちゃめちゃ)発展させながら、オーカワの運勢診断をアレンジしてみます。できるかな? オーカワから学ぶまで、僕はプログラミングとは暗記だと思っていたのですが、全然そんなこと...

てか僕の前のJavaScriptの記事から急激にプログラムが難しくなってますね(笑)

[WordPress][JavaScript]で運勢診断作ってみたー
どうもー最近JavaScriptを勉強しようと思ってきたオーカワです。 最近WordPressで「ここをこうしたい」とか「こう出来たらいいなー」って思っても、PHPだけだと出来ないことが多くて、JavaScriptわかればなーってのが...

ブログを書いた時は、初心者でしたが、今ではJavaScriptを使い、ブラウザからロボットを操作出来るようにしたり、家の照明装置やカメラを操作してます。

今はNode.jsを勉強中ってか、Node.jsを使ってとあるwebサーバを作ってます。出来たらブログに書くつもりなので、乞うご期待。

参考

JavaScriptによる順列組み合わせの生成 - Qiita
## 順列の生成 皆さんはじめまして。みやねゆうじと申します。今回がQiitaデビューです。 さて全ての要素の組み合わせを検査して最適解を求める問題がありますが、これは一般に全数検索アルゴリズムを適用して順列組み合わせを生成して解...

いつもお世話になっております。

The following two tabs change content below.

オーカワ

GCPばっか触ってるにゃーんエンジニア こちらのブログでも活躍中

コメント