inputタグに入力された文字列に応じてひらがなとカタカナの組み合わせでできる文字列のパターンを出力したいです。
例えば、かさという入力があった場合「かさ」「カサ」「かサ」「カさ」の4つが出力されるイメージです。
「カサ」→「かさ」や「かさ」→「カサ」は下記で作成できたのですが、「かサ」「カさ」といった混成パターンの作り方の検討がつかず質問させていただきました。
html
1<input type="text" id="input">
js
1$('#input').on('input', function(){ 2 var val = $(this).val(); 3 var kana = hiraToKana(val); 4 var hira = kanaToHira(val); 5 // ひらがな、カタカナの混成文字列を作る 6}) 7 8function hiraToKana(str) { 9 return str.replace(/[\u3041-\u3096]/g, function(match) { 10 var chr = match.charCodeAt(0) + 0x60; 11 return String.fromCharCode(chr); 12 }); 13} 14 15function kanaToHira(str) { 16 return str.replace(/[\u30a1-\u30f6]/g, function(match) { 17 var chr = match.charCodeAt(0) - 0x60; 18 return String.fromCharCode(chr); 19 }); 20}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
ひらがな、カタカナは2パターンなので、
文字数の二乗分まで二進数を生成して、
0か1かで一文字ずつひらがなとカタカナを判定しながら生成して連結する方法です。
追記
失礼しました。
0埋め用のサイズ指定が2で固定になっており、
かつパターンの数は文字数の2乗ではなく、2の文字数乗が正解でした。
修正した内容で試してみてください。
javascript
1var val = "かさ"; 2// ひらがな、カタカナの混成文字列を作る 3var retArray = []; 4 5var len = val.length; 6for (var i = 0; i < 2 ** len; i++) { 7 var retStr = ""; 8 // 二進数文字の0埋め 9 var zeroPadding = [...Array(len)].reduce((r, v) => r += "0", ""); 10 var bi = (zeroPadding + i.toString(2)).slice(-len);; 11 for (var j = 0; j < len; j++) { 12 var cbi = bi.charAt(j); 13 if (cbi === "0") { 14 retStr += kanaToHira(val.charAt(j)); 15 } else if (cbi === "1") { 16 retStr += hiraToKana(val.charAt(j)); 17 } 18 } 19 retArray.push(retStr); 20} 21console.log(retArray); 22 23function hiraToKana(str) { 24 return str.replace(/[\u3041-\u3096]/g, function(match) { 25 var chr = match.charCodeAt(0) + 0x60; 26 return String.fromCharCode(chr); 27 }); 28} 29 30function kanaToHira(str) { 31 return str.replace(/[\u30a1-\u30f6]/g, function(match) { 32 var chr = match.charCodeAt(0) - 0x60; 33 return String.fromCharCode(chr); 34 }); 35}
投稿2020/08/14 04:54
編集2020/08/14 06:42総合スコア2183
0
混成パターンの作り方の検討がつかず
たとえば、ひらがなを 0
に、カタカナを 1
に割り当てるなどして、2進数の処理を考えるだけでも取得できます。
javascript
1var 2 val ="かサ", 3 len = val.length, 4 ptn = val.split("").map(c=>[kanaToHira(c),hiraToKana(c)]), 5 max = (l=>{ 6 let r = 0; 7 while ( l-- ) { 8 r = (r<<1)|1 9 } 10 return r 11 })(len), // 最大インデックス値 12 ret = Array.from({length:max+1}).map((v,i)=> 13 i.toString(2).padStart(len,"0") 14 .split("").map((n,i)=>ptn[i][n]) 15 .join("") 16 ) 17; 18console.log( ret );
あんぶれら
だと32
パターン。きほんじょうほうしょり
だと2048
パターン。きほんじょうほうしょりぎじゅつしゃ
だと131072
パターン(遅い)。
試してみるとわかりますが、文字数が増えると混成パターンの取得には時間がかかります。
尚、回答例ですので、ひらがな、カタカナ以外の文字がある場合の対応は考えていません。
投稿2020/08/14 05:19
総合スコア5432
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんにちは
ベストアンサー決定後に失礼します。
一文字入力されたり、バックスペースで一文字削除されたりするたびに、毎回、入力文字に含まれるひらがな、またはカタカナの文字数の2の累乗個の文字列を作り直すと時間がかかるので、現在表示中のリストを保持しておいて、ひらがなまたはカタカナが一文字入力されたら、表示中のリストの各文字列から、入力文字のひらがなとカタカナを追加した文字列を作る、というやり方を考えました。
javascript
1$(function() { 2 3 const isHira = code => 0x3041 <= code && code <= 0x3096; 4 const isKata = code => 0x30A1 <= code && code <= 0x30F6; 5 6 class KanaStrings { 7 constructor() { 8 this.input = ''; 9 this.list = []; 10 } 11 12 getChars(ch) { 13 const code = ch.charCodeAt(0); 14 if (isHira(code)) { 15 return [String.fromCharCode(code), String.fromCharCode(code + 0x60)]; 16 } else if (isKata(code)) { 17 return [String.fromCharCode(code - 0x60), String.fromCharCode(code)]; 18 } else { 19 return [ch]; 20 } 21 } 22 23 add(ch) { 24 const chars = this.getChars(ch); 25 if (this.list.length === 0) { 26 this.list = chars; 27 } else { 28 if (chars.length === 1) { 29 this.list = this.list.map(str => `${str}${chars[0]}`); 30 } else { 31 this.list = this.list.map( 32 str => [`${str}${chars[0]}`, `${str}${chars[1]}`] 33 ).flat(); 34 } 35 } 36 } 37 38 remove() { 39 const code = this.list[0].charCodeAt(this.list[0].length - 1); 40 if (isHira(code) || isKata(code)) { 41 this.list = this.list.filter((_, i) => i%2).map(str => str.substring(0, str.length - 1)); 42 } 43 else { 44 this.list = this.list.map(str => str.substring(0, str.length - 1)); 45 } 46 if (this.list.length === 1 && this.list[0] === "") { 47 this.list.splice(0) 48 } 49 } 50 51 set(val) { 52 if (val.length >= this.input.length) { 53 let pos = -1; 54 for (let i=0; i < val.length; ++ i) { 55 if (val[i] !== this.input[i]) { 56 pos = i; 57 break; 58 } 59 } 60 if (pos >= 0) { 61 const rmStr = this.input.substring(pos); 62 if (rmStr) { 63 [...rmStr].forEach(_ => this.remove()); 64 } 65 const addStr = val.substring(pos); 66 if (addStr) { 67 [...addStr].forEach(ch => this.add(ch)); 68 } 69 } 70 } else { 71 this.remove(); 72 } 73 this.input = val; 74 return this; 75 } 76 } 77 78 79 const kanaStrings = new KanaStrings(); 80 81 $('#input').on('input', function(){ 82 const val = $(this).val(); 83 const items = kanaStrings.set(val).list.map((str, i) => `<li>${str}</li>`); 84 $('#result').empty().append(items); 85 }); 86 87});
- 動作確認用 CodePen: https://codepen.io/jun68ykt/pen/VwaegBz?editors=0010
・ひらがな、またはカタカナ以外の文字が入力されても、意図通り動くようになっていると思われます。
・カーソルが入力文字列の末尾にある状態で、バックスペースを押して一文字消すと、リスト内容も対応します。
・カーソルが入力文字列の末尾ではない場所にある状態で、バックスペースを押した場合の未対応対です。
以上、参考になれば幸いです。
投稿2020/08/14 08:46
総合スコア9058
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
総当り用の関数を一つ作ればよいのでは?
javascript
1<script> 2$(function(){ 3 $('#input').on('input', function(){ 4 var val = $(this).val(); 5 var moji=val.split(""); 6 var data=moji.map(x=>$.unique([hiraToKana(x),kanaToHira(x)])); 7 var r=soatari(data); 8 console.log(r); 9 }); 10}); 11function soatari(data){ 12 var res=[]; 13 if(data.length>0 && data instanceof Array){ 14 if(data.length==1){ 15 res=(data[0] instanceof Array)?data:[data]; 16 }else{ 17 if(!(data[0] instanceof Array)) data[0]=[data[0]]; 18 if(!(data[1] instanceof Array)) data[1]=[data[1]]; 19 for(i of data[0]) for(j of data[1]) res.push(i+j); 20 res=[res].concat(data.slice(2)); 21 if(typeof data[2]!=="undefined") res=soatari(res); 22 } 23 } 24 return [1,2].includes(data.length)?res[0]:res; 25} 26function hiraToKana(str) { 27 return str.replace(/[\u3041-\u3096]/g, function(match) { 28 var chr = match.charCodeAt(0) + 0x60; 29 return String.fromCharCode(chr); 30 }); 31} 32 33function kanaToHira(str) { 34 return str.replace(/[\u30a1-\u30f6]/g, function(match) { 35 var chr = match.charCodeAt(0) - 0x60; 36 return String.fromCharCode(chr); 37 }); 38} 39</script> 40<input type="text" id="input">
投稿2020/08/14 06:17
総合スコア114839
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/14 06:15 編集
2020/08/14 07:40