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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

4回答

1341閲覧

同音のひらがなとカタカナの組み合わせでできる文字列のパターンを作りたい

raidomaru

総合スコア106

JavaScript

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2020/08/14 03:15

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ページで確認できます。

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

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

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

guest

回答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
yureighost

総合スコア2183

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

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

raidomaru

2020/08/14 06:15 編集

ご回答ありがとうございます。 2文字の時は想定通りの配列が作成できました。 3文字以上にすると想定外の結果となっていまいました。 よろしければ引き続きアドバイス頂けると助かります。 var val = "しゃつ"とした場合、しゃつが重複する ["しゃつ", "しゃツ", "しャつ", "しャツ", "シゃつ", "シゃツ", "シャつ", "シャツ", "しゃつ"] var val = "かさたて"とした場合、3文字のものがある  ["かさた", "かさタ", "かさタて", "かさタテ", "かサたて", "かサたテ", "かサタて", "かサタテ", "カさたて", "カさたテ", "カさタて", "カさタテ", "カサたて", "カサたテ", "カサタて", "カサタテ"]
raidomaru

2020/08/14 07:40

ありがとうございます。 修正いただいたもので想定通りの動作確認できました。
guest

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 );
  1. あんぶれらだと 32パターン。
  2. きほんじょうほうしょりだと 2048パターン。
  3. きほんじょうほうしょりぎじゅつしゃだと 131072パターン(遅い)。

試してみるとわかりますが、文字数が増えると混成パターンの取得には時間がかかります。
尚、回答例ですので、ひらがな、カタカナ以外の文字がある場合の対応は考えていません。

投稿2020/08/14 05:19

AkitoshiManabe

総合スコア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});

・ひらがな、またはカタカナ以外の文字が入力されても、意図通り動くようになっていると思われます。
・カーソルが入力文字列の末尾にある状態で、バックスペースを押して一文字消すと、リスト内容も対応します。
・カーソルが入力文字列の末尾ではない場所にある状態で、バックスペースを押した場合の未対応対です。

以上、参考になれば幸いです。

投稿2020/08/14 08:46

jun68ykt

総合スコア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

yambejp

総合スコア114839

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問