質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

979閲覧

【JavaScript】配列操作について

0918Nobita

総合スコア9

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/02/02 04:34

編集2017/02/02 04:54

lang

1['(', '*', '(', '+', 2, 4, ')', 3, ')']

上のような配列ひとつを引数にとり、

lang

1['*', ['+', 2, 4], 3]

このような配列に変換して返す関数を定義したいのですが、
渡された配列の要素を順に検証していき '('')' に反応して再帰処理を行い
配列の配列を生成していくコードがなかなか書けません。

定義コードをお教えいただくか、効率的なアルゴリズムの説明をしていただけると嬉しいです。

追記:常に要素は()で括られているものとします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2017/02/02 04:50

()で括られていない要素はどうなるのでしょうか。
0918Nobita

2017/02/02 04:52

常に要素は()で括られているものとします。説明不足ですみません
guest

回答2

0

ベストアンサー

なかなか興味深い課題なので自分で書いてみました。

javascript

1function f(input){ 2 input = input.slice(1, -1); // 最初と最後の括弧は固定なので切り捨てる 3 function g(ary){ 4 var elm; 5 while(input.length){ 6 elm = input.shift(); // 先頭の要素を取得。同時にその要素をinputから捨てる 7 if(elm === "(") ary.push(g([])); // もし "(" なら再帰的に新しい配列を挿入する 8 else if(elm === ")") break; // もし ")" なら再帰的な配列挿入は終了する 9 else ary.push(elm); // それ以外なら現在の配列に挿入する 10 } 11 return ary; 12 } 13 return g([]); 14} 15 16f(['(', '*', '(', '+', 2, 4, ')', 3, ')']); // ["*",["+",2,4],3] 17f("(((a)))".split("")); // [[["a"]]] 18f("((a)((aa)(a)(a))(aa))".split("")); // [["a"],[["a","a"],["a"],["a"]],["a","a"]] 19

ただ、上のコードではエラーチェックをしていません。
エラーチェックもするならこんな感じにします。

javascript

1function f(input){ 2 if(!Array.isArray(input) || input[0] != "(" || input[input.length-1] != ")") throw new Error; // inputが配列かどうか、最初と最後の要素が正しいかどうかをチェックする 3 input = input.slice(1, -1); 4 function g(ary, top){ 5 var elm; 6 while(input.length){ 7 elm = input.shift(); 8 if(elm === "(") ary.push(g([], false)); 9 else if(elm === ")"){ 10 if(top) throw new Error; // 最上位の配列に挿入中なのに、")" が来るのはおかしい 11 else break; 12 } 13 else ary.push(elm); 14 } 15 if(!top && elm != ")" && input.length == 0) throw new Error; // 下位の配列に挿入中なのに、inputの要素がなくなるのはおかしい 16 return ary; 17 } 18 return g([], true); 19} 20 21f(['(', '*', '(', '+', 2, 4, ')', 3, ')']); // ["*",["+",2,4],3] 22f(['(', '*', '(', '+', 2, 4, ')', 3]); // エラー。最後の括弧がない 23f(['(', '*', '(', '+', 2, 4, 3, ')']); // エラー。閉じてない括弧がある 24f(['(', '*', '+', 2, 4, ')', 3, ')']); // エラー。括弧が開いていないのに閉じている

効率的なアルゴリズムかどうかは自信がありませんが、参考にしていただければと思います。

投稿2017/02/02 05:42

編集2017/02/02 05:42
kura

総合スコア368

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0918Nobita

2017/02/02 05:57

なるほど、与えられた配列からshiftで要素を切り出しながら新たに配列を生成していくんですね。自分は与えられた配列を直接操作して目的の状態に遷移させることばかり考えていたのですごく勉強になりました。ありがとうございます!(この関数はテキストエリアでの入力を変換するためのもので、S式で記述する自作言語のインタプリタで利用するつもりです)
guest

0

でけた! (ことにして) 

js

1var arr = ['(', '*', '(', '+', 2, 4, ')', 3, ')']; 2var str = '['; 3arr.map(v => v === '(' ? '[' : v === ')' ? ']' : isNaN(v) ? `"${v}"` : v).reduce((a, b, i) => { 4 str += (a === '[' || b === ']' ? '' : ',') + b; 5 return b; 6}); 7var result = JSON.parse(str); 8console.log(result);

これ以上は無理!! (じゃないのはわかってる)
再帰してない・・・・ゴメンこの回答は無し。

投稿2017/02/02 05:48

編集2017/02/02 05:55
turbgraphics200

総合スコア4269

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問