javascriptで簡単な分配法則を実現する方法を考える
目次を開く
例えば3(4x-1)の場合を考える
今回は例えば3(4x-1)の場合を考えてみます。
この場合は \[ 3(4x-1)=3×4x+3×(-1)ですよね \]
プログラムでこれをどう実現するかを考えます。
()のついている位置の取得
まずはじめに(と)がついてる位置を取得します。
math_string='3(4x-1)'; //文字列って何も処理しなくても実はデフォルトで配列に入ってることが判明してます笑 var kekka =[]; for(var i=0;i< math_string.length; i++){ if(math_string[i]=='(' || math_string[i]==')'){ kekka.push(i); } }
これでkekkaに1,6が入ってます。一番初めは0なので
ということで(もしくは)がついている位置は1,6と取得できました。
つまり2~5の位置に()内の数値もしくは+か-が入ってるわけですね
\[ 3(4x-1) \] のうちの \[ 4x-1 \]の部分ですね。
()内の部分だけ取り出してみます
今はどんな感じになっているかというと
kekka[0]=1,kekka[1]=6・・・というように(と)の位置が交互に入っているのでその間の2~5、7~11とかの部分だけを取り出せばいいですよね。
文字列の一部だけを切り出したい場合は
文字列が入った変数.substring( 取り出し開始位置, 取り出し終了位置の一個次 );
を使います
var kiridasi=[]; for(var count=0; count< kekka.length; count=count+2){ kiridasi.push(math_string.substring(kekka[count]+1,kekka[count+1])); }
これでkiridasi[0]に4x-1が入りました。
4x-1をさらに分解する
次は4x-1を4xと-1に分けて配列に格納します。
つまり+もしくは-があればそこで区切ればいいことになります。
同じようにやっていくだけです。
var kekka2=[]; for(var i=0; i< kiridasi[0].length; i++){ if(kiridasi[0][i]=='+' || kiridasi[0][i]=='-'){ kekka2.push(i); } }
これで配列kekka2[0]に4x-1の-の場所2が入りました
これを4xと-1に分けます。今回は+-の符号を残します。
var kiridasi2=[]; //kiridasi[0]に+もしくは-が何個あるか var count2 = ( kiridasi[0].match( /-/g ) || [] ).length ; var count3 = ( kiridasi[0].match( /\+/g ) || [] ).length ; //kiridasi[0]の項数 var kousu_1 =count2+count3+1; //kiridasi[0]の最初の項が-だったら項数は一つ減る if(kiridasi[0].charAt(0)=='-'){ var kousu_1=count2+count3; } //最初の項の取り出し //kiridasi[0]の最初の項が-だったら取り出し箇所がずれる if(kiridasi[0].charAt(0)=='-'){ kiridasi2.push(kiridasi[0].substring(kekka2[0],kekka2[1])); } else{ kiridasi2.push(kiridasi[0].substring(0,kekka2[0])); } //途中の項の取り出し if(kousu_1>=2){ //kiridasi[0]の最初の項が-だったら取り出し箇所がずれる if(kiridasi[0].charAt(0)=='-'){ for(var s=1; s< kousu_1-1;s++){ kiridasi2.push(kiridasi[0].substring(kekka2[s],kekka2[s+1])); } } else{ for(var s=0; s< kousu_1-2;s++){ kiridasi2.push(kiridasi[0].substring(kekka2[s],kekka2[s+1])); } } } //最後の項の取り出し kiridasi2.push(kiridasi[0].substring(kekka2[kekka2.length-2],kiridasi[0].length));
これでkiridasi2[0]に4x、kiridasi2[1]に-1が入りました。
ここで一度分配させます
ここで一度分配計算をして計算が済んだ数式は削除して続けるという名案が思いつきましたが今回は3(4x-1)ですのでこの分配計算が済めば終了となります。
初めて出てくる(の位置はkekka[0]に1として入っているのでその前の数を取り出します。
var first_suji=math_string.substring(0,kekka[0]); //初めの数字が-なら()をつける if(first_suji.charAt(0)=='-'){ first_suji=("("+first_suji+")"); }
これでfirst_sujiに3が入っています。
あとはfirst_suji×kiridasi2[0]+first_suji×kiridasi2[1]+・・・・を表示していけばいいだけですね
最後に+が入らないようにして、また-が入っている場合は()でくくっておくことにします。
var keisan_kekka=""; for(var i=0; i< kiridasi2.length; i++){ //最後は+なし if(i==kiridasi2.length-1){ //最後も-がついてる場合は()をつける if(kiridasi2[i].includes('-')==true){ keisan_kekka =keisan_kekka.concat(first_suji+"×("+kiridasi2[i]+")"); } else{ keisan_kekka =keisan_kekka.concat(first_suji+"×"+kiridasi2[i]); } } //-がついてる場合は()をつける else if(kiridasi2[i].includes('-')=true){ keisan_kekka =keisan_kekka.concat(first_suji+"×("+kiridasi2[i]+")+"); } //それ以外は普通に else{ keisan_kekka =keisan_kekka.concat(first_suji+"×"+kiridasi2[i]+"+"); } }
関数にする
できたので関数にしておきます
function bunpai_1(math_string){ //文字列って何も処理しなくても実はデフォルトで配列に入ってることが判明してます笑 var kekka =[]; for(var i=0;i< math_string.length; i++){ if(math_string[i]=='(' || math_string[i]==')'){ kekka.push(i); } } var kiridasi=[]; for(var count=0; count< kekka.length; count=count+2){ kiridasi.push(math_string.substring(kekka[count]+1,kekka[count+1])); } var kekka2=[]; for(var i=0; i< kiridasi[0].length; i++){ if(kiridasi[0][i]=='+' || kiridasi[0][i]=='-'){ kekka2.push(i); } } var kiridasi2=[]; //kiridasi[0]に+もしくは-が何個あるか var count2 = ( kiridasi[0].match( /-/g ) || [] ).length ; var count3 = ( kiridasi[0].match( /\+/g ) || [] ).length ; //kiridasi[0]の項数 var kousu_1 =count2+count3+1; //kiridasi[0]の最初の項が-だったら項数は一つ減る if(kiridasi[0].charAt(0)=='-'){ var kousu_1=count2+count3; } //最初の項の取り出し //kiridasi[0]の最初の項が-だったら取り出し箇所がずれる if(kiridasi[0].charAt(0)=='-'){ kiridasi2.push(kiridasi[0].substring(kekka2[0],kekka2[1])); } else{ kiridasi2.push(kiridasi[0].substring(0,kekka2[0])); } //途中の項の取り出し if(kousu_1>=2){ //kiridasi[0]の最初の項が-だったら取り出し箇所がずれる if(kiridasi[0].charAt(0)=='-'){ for(var s=1; s< kousu_1-1;s++){ kiridasi2.push(kiridasi[0].substring(kekka2[s],kekka2[s+1])); } } else{ for(var s=0; s< kousu_1-2;s++){ kiridasi2.push(kiridasi[0].substring(kekka2[s],kekka2[s+1])); } } } //最後の項の取り出し kiridasi2.push(kiridasi[0].substring(kekka2[kekka2.length-1],kiridasi[0].length)); //(の前の数字の取り出し var first_suji=math_string.substring(0,kekka[0]); //初めの数字が-なら()をつける if(first_suji.charAt(0)=='-'){ first_suji=("("+first_suji+")"); } var keisan_kekka=""; //いよいよ分配計算をする for(var i=0; i< kiridasi2.length; i++){ //最後は+なし if(i==kiridasi2.length-1){ //最後も-がついてる場合は()をつける if(kiridasi2[i].includes('-')==true){ keisan_kekka =keisan_kekka.concat(first_suji+"×("+kiridasi2[i]+")"); } else{ keisan_kekka =keisan_kekka.concat(first_suji+"×"+kiridasi2[i]); } } //-がついてる場合は()をつける else if(kiridasi2[i].includes('-')==true){ keisan_kekka =keisan_kekka.concat(first_suji+"×("+kiridasi2[i]+")+"); } //それ以外は普通に else{ keisan_kekka =keisan_kekka.concat(first_suji+"×"+kiridasi2[i]+"+"); } } return keisan_kekka; }//関数終わり
関数の説明と使い方
この関数は4(4x-8y-9-4z)などの数値×(多項式)などを分配する関数です。
var math_string='4(4x-8y-9-4z)';
などと入力すると
4×4x+4×(-8y)+4×(-9)+4×(-4z)
と結果が返ってきます
みんなが計算できるようにする
\[ -34(3x-45y-4xz-4z) \]などと入力すると分配した答えが返ってきます。
数式を入力して下さい。