実現したいこと
こんにちは、お世話になっております。
私は今回、平仮名からローマ字に変換するプログラムを作成したいと思っています。
入力値を受け取りarraylistでローマ字に変換したものを返すというものです。
入力例
しょうぼうしゃ わいんぐらす
出力例
[shoubousha, shoubousya, syoubousha, syoubousya] [wainngurasu, waingurasu]
聞きたいこと
「しょ」なら「sho」、「ん」なら「nn」などとし、
shoubousha wainngurasu
と出力される(上記の入力例の場合)プログラムなら作成できるのですが、上記のように出力するにはどのようなコードを書けばよいのかが分かりません。
皆様ならどのようなコードを書くか、教えて頂きたいと思い、質問させていただきました。
補足情報
JDK 10.0.2
Eclipse 4.7 Oxygen
不足している情報があればご指摘下さい。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 09:09
2018/08/31 09:23
回答7件
0
ヘボン式だとか日本式だとかで全パターンを網羅したいってことですよね。
じゃあ全パターン分の変換用マップを用意しましょう。
1対1のマップにならないなら、配列にしちゃえばいいです。
'し' → ['si', 'shi']
的な。
変換しようとして配列が取れた文字の分だけ、全パターンを組み合わせてあげればいいです。
とりあえず質問する前に、自分でこうだろうと思うものを作ってみてください。
超絶冗長なコードでもいいじゃないですか。
if
とループさえあればほぼなんでもできます。
投稿2018/08/30 14:00
総合スコア1803
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/30 23:02
2018/08/31 08:59
0
ベストアンサー
「しょうぼうしゃ」とかは難しいので、「しか」とか「もち」とかの簡単な文字列から初めてみてはどうでしょう。
まずは、Mapオブジェクトで変換表を作りましょう。
キーはひらかな1文字、値は取りうるローマ字パターンの配列です。
ローマ字が1パターンしかない場合でも配列にします。
java
1Map<String, String[]> = new HashMap<String, String[]> 2map.put("し", new String[]{"si","shi"}); 3map.put("か", new String[]{"ka"});
こんな感じで、とりあえず問題で使う文字列だけで良いので作りましょう。
次に、問題の文字を1文字ずつ配列に変換していきます。
今回は「しか」なので、「し」と「か」に分割できます。分割する方法は自分で考えてください。
"java String 1文字ずつ分解" で検索するといろいろ出てくると思います。
"し"は{"si","shi"}、"か"は{"ka"}が対応すると思います。
取りうるパターンは2x1=2パターンです。
取りうるすべての組み合わせを文字列連結すれば答えが出てきます。
これをプログラムで行うには、ひらがな1文字分ずつループさせます。
java
1List<String> result = new ArrayList<>(); //答えを入れるリスト 2for(int i = 0; i < hiragana.length; i++){ //<-hiraganaは「しか」が1文字ずつ入っている 3 String[] romajiArray = map.get(hiragana[i]); // あらかじめ登録したローマ字パターン配列を取得 4 if(result.size() == 0){ //最初は答えリストは空なので、配列の中身をそのままresultへaddする 5 //省略。自分で考えてね 6 }else{ //2文字目以降はすでにローマ字が入っているのでelseへ 7 //すでに入っている文字列と次の文字のパターンの組み合わせを登録する 8 //ここも自分で考えてね 9 } 10}
自分で考えてね、と書いた部分はこの課題のコアの部分です。試行錯誤してください。
問題文を見るに、ひらがな1文字→ローマ字1パターンはできていると思います。それに対してローマ字側が配列になり、forで繰り返しが発生するだけです。順序よくやればちゃんと解決できますので頑張ってください。
自分でソースを書いてみて、詰まったらどこで詰まったかを明確にして再質問しましょう。
コードを書いてくればコードで答えてもらえるでしょう。
※初心者には若干難易度が高い課題かなぁとは思います。
※拗音はともかく促音が入ってくると途端に難しくなるけど今のところは無視していいでしょう。
投稿2018/08/30 14:47
総合スコア4447
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/30 23:06
2018/08/31 08:55
2018/08/31 09:46
0
この問題は、例にある「しょうぼうしゃ」と「わいんぐらす」では難易度が異なります。
「わいんぐらす」は言葉の順序通りに処理を進めても問題ありませんが、「しょうぼうしゃ」を同じように言葉の頭から処理を行うと判定ロジックが複雑になります。
最初の文字「し」を見て、[shi]、[si]の2パターンを用意した後、次の文字「ょ」を見て「lyo」、「xyo」を繋げると、
[shilyo,shixyo,silyo,sixyo]となり、目的の[sho,syo]は生まれません。
(そもそも小さい「よ」をコンピュータ入力する方法であるlyoやxyoをローマ字と定義して良いかは別途考える必要がありますが、、、)
この場合の解決策としては、文字を後ろから判定する方法が考えられます。
ひらがなは「きゃ、きゅ、きょ」や「ふぁ、ぐぁ」などを踏まえても最大2文字までの為、
後ろから1文字ずつ判定し、「ぁ、ぃ、ぅ、ぇ、ぉ、ゃ、ゅ、ょ」の場合はさらにもう1文字前の文字と合わせた2文字でローマ字に変換すれば、前から判定を行うよりも簡単に書けるのと思います。
また、ひらがなとローマ字の変換については、他の方々がアドバイスされている通り、変換表をMap型に作成する方法が簡単ですが、witch文を用いることでも実現可能です。(Java7以降のみです)
Mapで処理するよりも高速に処理されるという話も耳にするのでご参考までに。
(今回の例題のような場合にはほぼ影響しない、差が感じられないと思いますが)
Java
1switch (str) { 2 case "きゃ" : 3 // TODO:文字列生成処理; 4 break; 5 case "きゅ" : 6 // TODO:文字列生成処理; 7 break; 8 :
投稿2018/08/30 18:36
編集2018/08/30 18:41総合スコア118
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
java ひらがな ローマ字 変換
で google 検索してみました。
- ひらがなからローマ字への文字列変換
http://syunpon-java.com/programing/java/sample/hiragana2roma.shtml
- 漢字/カタカナ/ひらがなをローマ字に変換するJavaライブラリ
https://askjapan.me/q/Java-36080758093
他にもいろいろな情報をみつけられると思います。
投稿2018/08/30 13:22
総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/30 13:36
0
投稿2018/08/30 22:23
総合スコア5737
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 09:01
0
javaでなくて申し訳ありませんが、pythonで
Pythonでひらがな/カタカナとローマ字を相互に変換する
というのがあります。私はpythonで使わせてもらってます。pythonで動かしていますがなかなか良いです。
ソースがあるので自分好みに変更可能ですし。
pythonのソースですがコードが載ってますのでjavaに書き変えてみたらいかがでしょうか。
投稿2018/08/30 13:56
総合スコア1167
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/30 14:01
0
自分への課題と思いながら汎用的に作ろうとしたので思ったより難しかったです。
「しょうぼうしゃ」の変換は出来ましたので参考までに。
2文字のパターンと1文字のパターンを辞書登録さえすればなんでも変換出来るはずです。
(未検証)
取り急ぎ全体の流れの参考になればと思います。
回答編集:
辞書のみ質問者さんのコードより拝借し差し替えました。
###出力結果
//しょうぼうしゃ
//[shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya, shoubousha, syoubousya, cilyouboucilya, cixyouboucixya, silyoubousilya, sixyoubousixya, shilyouboushalya, shixyouboushaxya]
java
1import java.util.ArrayList; 2import java.util.HashMap; 3import java.util.Map; 4 5public class memo201 { 6 7 public static void main(String[] args) { 8 9 //辞書作成 10 //辞書のみ質問者さんのコードより拝借し差し替え 11 makeMap(); 12 13 //入力 14 String s = "しょうぼうしゃ"; 15 16 //処理 17 ArrayList<String> ans = new ArrayList<String>(); 18 ans = kanaToRoma(s); 19 20 //出力 21 System.out.println(ans); 22 } 23 24 private static ArrayList<String> kanaToRoma(String kana) { 25 ArrayList<String> result = new ArrayList<String>(); 26 ArrayList<String> tmp = new ArrayList<String>(); 27 result.add(""); 28 29 final int n = kana.length(); 30 int t = 1;//通り 31 32 boolean is2Char = false; 33 34 for (int i = 0; i < n - 1; i++) { 35 36 //"しょ"などの2文字のものがmapにあるか確認 37 String key = kana.substring(i, i + 2); 38 39 if (map.containsKey(key)) { 40 is2Char= true; 41 }else { 42 is2Char = false; 43 key = kana.substring(i, i + 1); 44 } 45 46 //組み合わせの数だけ配列を増やす 47 //しゃ=sha,sya=2通り 48 //2通りなら2倍 49 int p = map.get(key).length; 50 51 t *= p;//全通り組み合わせ数 52 53 //加工用配列に前回までの処理内容を移す 54 tmp.clear(); 55 tmp.addAll(result); 56 57 for (int x = 0; x < p - 1; x++) { 58 result.addAll(tmp); 59 } 60 tmp.clear(); 61 62 int q = result.size(); 63 64 String[] list = map.get(key); 65 66 int k = 0; 67 for (int j = 0; j < q; j++) { 68 69 tmp.add(result.get(j) + list[k]); 70 if (k == list.length - 1) { 71 k = 0; 72 } else { 73 k++; 74 } 75 } 76 77 //加工用配列から戻り値用配列へデータを移す 78 result.clear(); 79 result.addAll(tmp); 80 81 //2文字処理時のみインクリメントを2文字分進める 82 if(is2Char) { 83 i++; 84 } 85 } 86 return result; 87 } 88 89 private static Map<String, String[]> map = new HashMap<>(); 90 91 private static void makeMap() { 92 map.put("う", new String[] {"u"}); 93 map.put("し", new String[] {"si", "shi", "ci"}); 94 map.put("ぼ", new String[] {"bo"}); 95 map.put("しゃ", new String[] {"sha", "sya", "cilya" , "cixya", "silya", "sixya", "shalya", "shaxya"}); 96 map.put("しょ", new String[] {"sho", "syo", "cilyo" , "cixyo", "silyo" , "sixyo", "shilyo" , "shixyo"}); 97 } 98} 99
投稿2018/08/31 06:37
編集2018/08/31 10:19総合スコア1009
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/31 09:03
2018/08/31 09:12
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。