前提・実現したいこと
ここで質問した者です。
質問に対する回答によってある程度は実現できたのですが、促音の処理で問題が発生しています。ご指摘お願いします。
入力例
かっぱ さっし
期待する出力例
[kaltupa, caltupa, kaxtupa, caxtupa, kappa, cappa] [saltusi, saxtusi, sassi, saltushi, saxtushi, sasshi, saltuci, saxtuci, sacci]
入力例に対する実際の出力例
[kaltupa, caltupa, kaxtupa, caxtupa, kappa, cappa] [saltusi, saxtusi, sassi, sacsi, saltushi, saxtushi, sasshi, sacshi, saltuci, saxtuci, sasci, sacci]
問題なのは、実際の出力に「sacsi」、「sacshi」、「sasci」が含まれていることです。
該当のソースコード
字数制限に引っかかったのでこちらからお願いします。
補足情報
JDK 10.0.2
Eclipse 4.7 Oxygen
不足している情報があれば是非ご指摘下さい。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
リンク先のソースを見る限り、もう実装はできている模様ですが、「私ならこうする」を。
促音「っ」のローマ字化パータンは、
- ltu
- xtu
- 次のひらがなの子音
の3パターンと思います。
(っあ、とか、っお、など促音+母音は今回は除外)
1番目と2番目は素直に変換できますが、3番目は、とりあえず仮置きの記号"#"で変換することにします。
java
1//促音で次の子音が重なるパターンは一旦#をセットする 2kanaMap.put("っ",new String[]{"ltu","xtu","#"});
これを使って、「かっぱ」を今までと同じように変換します。するとこうなりますね。
{"kaltupa", "kaxtupa", "ka#pa"}
で、リストが出来上がった後に、結果文字列それぞれを「#は次のアルファベットで置換する」正規表現で置換します。
java
1"ka#pa".replaceAll("#(.)","$1$1") // ka#pa -> kappa
(正確には、#と次の1文字を、「次の1文字」2つで置換している)
こうすれば、今までのプログラムを大きく変えることなく促音に対応できると思います。
参考として、前の回答を作る前に参考実装したソースを連携します。
java
1import java.util.*; 2import java.util.stream.*; 3 4public class HelloWorld{ 5 6 public static void main(String []args){ 7 8 //かなとローマ字変換マップ。文字数の多い順に並べる。 9 //keyは変換元文字列で、valueはパターン分の配列を持つ 10 Map<String, String[]> kanaMap = new LinkedHashMap<>(); 11 kanaMap.put("しょ",new String[]{"syo","sho"}); 12 kanaMap.put("しゃ",new String[]{"sya","sha"}); 13 kanaMap.put("し",new String[]{"si","shi"}); 14 kanaMap.put("う",new String[]{"u"}); 15 kanaMap.put("ぼ",new String[]{"bo"}); 16 kanaMap.put("か",new String[]{"ka","ca"}); 17 kanaMap.put("ぱ",new String[]{"pa"}); 18 //促音で次の子音が重なるパターンは一旦#をセットする 19 kanaMap.put("っ",new String[]{"ltu","xtu","#"}); 20 21 //変換対象ひらがな 22 String target = "しっしょう"; 23 //ひらがなごとにローマ字のパターン配列を保持するリスト 24 List<String[]> romaList = new ArrayList<>(); 25 //結果リスト 26 List<String> result = new ArrayList<>(); 27 28 //先頭から1モーラずつマッチングしていき、パターン配列を1ずつaddする 29 while(target.length() > 0){ 30 for( String key : kanaMap.keySet()){ 31 if(target.startsWith(key)){ 32 romaList.add(kanaMap.get(key)); 33 //マッチしたら先頭文字は消す 34 target = target.replaceFirst(key,""); 35 continue; 36 } 37 } 38 } 39 //リスト中間出力確認 40 //romaList.forEach((v)->System.out.println(Arrays.toString(v))); 41 42 //パターン配列を先頭から合成していきパターンリストを作る 43 for(String[] l : romaList){ 44 //先頭は素直に全要素追加 45 if(result.size() == 0 ){ 46 for(String s:l){ 47 result.add(s); 48 } 49 }else{ 50 //前の要素×次の要素の組み合わせをすべて追加 51 //新しいリストを作ってそっちへ入れる 52 List<String> newResult = new ArrayList<>(); 53 for(String s1: result){ 54 for(String s2: l){ 55 newResult.add(s1+s2); 56 } 57 } 58 //リストの洗い替え 59 result.clear(); 60 result = newResult; 61 } 62 } 63 //促音の"#"をstreamでエレガントに置換 64 result = result.stream().map(s->s.replaceAll("#(.)","$1$1")).collect(Collectors.toList()); 65 66 //結果出力 67 System.out.println("Result ->"); 68 System.out.println(Arrays.toString(result.toArray())); 69 } 70}
投稿2018/08/31 11:18
総合スコア4447
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 11:22
2018/08/31 11:29
2018/08/31 11:52
0
コード見たら、拗音をまとめて処理みたいなんですね。
今更の感もありますが、この手は、一文字先読みでの処理の方が良かった感。
ちょっと具体的なコードまで書けないのですが、一文字先読みで、次の文字を見て今の文字を処理する。2文字目が拗音だっら、拗音をキーにして最初の文字を引くみたいな。
で、促音も同じ。次の文字見て、次の文字の子音を重ねる。ch の前は、tを置くとあるようですが (opyonさん) chとなるのは、タ行なので、tで問題無いですね。
具体的にどうするかは、ちょっと考えてみたいですが、間に合うか。
投稿2018/08/31 11:24
総合スコア6383
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 11:28
0
出力例を見る限り「促音」は次の子音を重ねるルールだけではダメそうですね。
質問者さんの考える範囲をもう少し例題として提示して頂いたほうが回答を得やすくなる気がします。
「促音」の「定義」や「範囲」を回答者さんが調べるより現状調べてる質問者さんから情報を出して頂いたら手間が省けると思います。
私はアルゴリズム的なものは思いつかないので全通りの辞書出力ツールかエクセルで作ってコピペで辞書登録するかも。
map.put("っ◯", new String[] {"◯◯", "◯◯", "◯◯"});
次の文献の中にある「促音」を参考にして実装すれば出来るかも知れませんね。
日本語のローマ字表記の推奨形式
投稿2018/08/31 11:01
編集2018/08/31 11:05総合スコア1009
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 11:18
0
「っ」があったら次のひらがなをみて、その子音と同じ子音を重ねる
これじゃだめ?
投稿2018/08/31 10:32
総合スコア20651
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 11:08
0
java
1map.put("っぱ", new String[] {"ltupa", "xtupa", "ppa"});
でいけそうな気もしますが、一つ一つ登録するのは‥。
っ
+ 何か
で汎用的にしないと。
投稿2018/08/31 10:10
総合スコア16731
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 10:17
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。