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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

7回答

7898閲覧

平仮名からローマ字への変換

CreeperSaviour

総合スコア129

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/08/30 13:10

編集2018/08/30 13:11

実現したいこと

こんにちは、お世話になっております。

私は今回、平仮名からローマ字に変換するプログラムを作成したいと思っています。
入力値を受け取りarraylistでローマ字に変換したものを返すというものです。

入力例

しょうぼうしゃ わいんぐらす

出力例

[shoubousha, shoubousya, syoubousha, syoubousya] [wainngurasu, waingurasu]

聞きたいこと

「しょ」なら「sho」、「ん」なら「nn」などとし、

shoubousha wainngurasu

と出力される(上記の入力例の場合)プログラムなら作成できるのですが、上記のように出力するにはどのようなコードを書けばよいのかが分かりません。
皆様ならどのようなコードを書くか、教えて頂きたいと思い、質問させていただきました。

補足情報

JDK 10.0.2
Eclipse 4.7 Oxygen

不足している情報があればご指摘下さい。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

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

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

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

fuzzball

2018/08/31 07:16 編集

単語単位で何かの方式に従うというわけではなく、一文字単位で各種方式に変換して組み合わせるということでしょうか?(「ん」が「nn」に、「しょうぼうしゃ」が「shoubousya」や「syoubousha」に、なるような方式は聞いたことがないので)出力の目的を教えていただけますか?
CreeperSaviour

2018/08/31 09:09

「しょうぼうしゃ」の入力値に対し「shoubousya」や「syoubousha」等を返り値として求めている理由は、私が開発しているタイピングソフトで使おうと思っています。(1回のタイプごとの正誤判定)
fuzzball

2018/08/31 09:23

なるほど。納得しました。
guest

回答7

0

ヘボン式だとか日本式だとかで全パターンを網羅したいってことですよね。
じゃあ全パターン分の変換用マップを用意しましょう。
1対1のマップにならないなら、配列にしちゃえばいいです。
'し' → ['si', 'shi']的な。
変換しようとして配列が取れた文字の分だけ、全パターンを組み合わせてあげればいいです。

とりあえず質問する前に、自分でこうだろうと思うものを作ってみてください。
超絶冗長なコードでもいいじゃないですか。
ifとループさえあればほぼなんでもできます。

投稿2018/08/30 14:00

spookybird

総合スコア1803

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

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

CreeperSaviour

2018/08/30 23:02

回答有り難うございます。 今、spokeybirdさん、hope_mucciさん、Slimbさんの回答を参考にプログラムを作成しているのでお待ちくだされば幸いです。
CreeperSaviour

2018/08/31 08:59

促音には対応していませんが https://pastebin.com/R8Fh04W1 が書き終わったコードです。spokeybirdさんの回答も取り入れさせていただきました。 誠にありがとうございました。
guest

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

hope_mucci

総合スコア4447

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

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

CreeperSaviour

2018/08/30 23:06

回答有り難うございます。 今、spokeybirdさん、hope_mucciさん、Slimbさんの回答を参考にプログラムを作成しているのですが、hope_mucciさんが簡単なコードを書いてくださったので、順調に作成することが出来ています。 完全にコードが書き終わり次第、hope_mucciさんをベストアンサーにさせて頂きたいと思います。
CreeperSaviour

2018/08/31 08:55

hope_mucciさんが書かれたように促音で詰まったので他の場所で再質問させていただきます。 良ければ、そちらのコードを見ていただければ幸いです。
guest

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
Simb

総合スコア118

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

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

CreeperSaviour

2018/08/31 08:57

Slimbさん、回答有り難うございます。 回答を参考にさせていただきます。
guest

0

java ひらがな ローマ字 変換
で google 検索してみました。

  • ひらがなからローマ字への文字列変換

http://syunpon-java.com/programing/java/sample/hiragana2roma.shtml

  • 漢字/カタカナ/ひらがなをローマ字に変換するJavaライブラリ

https://askjapan.me/q/Java-36080758093

他にもいろいろな情報をみつけられると思います。

投稿2018/08/30 13:22

katoy

総合スコア22324

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

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

CreeperSaviour

2018/08/30 13:36

回答有り難うございます。 せっかく回答していただいたのですが、私が求めている機能は調べても見つけきることは出来ませんでした。 もしkatoyさんが良い案をお持ちでしたら是非お教え下さい。
guest

0

投稿2018/08/30 22:23

hichon

総合スコア5737

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

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

CreeperSaviour

2018/08/31 09:01

回答有り難うございます。 こちらは私が求めているような機能ではないかと思ったので、参考には出来ませんでした。わざわざリンクを張っていただいたのに申し訳ありません。
guest

0

javaでなくて申し訳ありませんが、pythonで
Pythonでひらがな/カタカナとローマ字を相互に変換する
というのがあります。私はpythonで使わせてもらってます。pythonで動かしていますがなかなか良いです。
ソースがあるので自分好みに変更可能ですし。
pythonのソースですがコードが載ってますのでjavaに書き変えてみたらいかがでしょうか。

投稿2018/08/30 13:56

ikapy

総合スコア1167

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

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

CreeperSaviour

2018/08/30 14:01

回答有り難うございます。 私はpythonのコードが全く読めないので、扱うことはできなさそうです。せっかく回答していただいたのですが、、申し訳ありません。
guest

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
opyon

総合スコア1009

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

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

CreeperSaviour

2018/08/31 09:03

回答有り難うございます。 促音には対応していませんが https://pastebin.com/R8Fh04W1 が私の書いたコードです。わざわざコードを張っていただいたのですが、ここまで書くと参考にはできなさそうです。申し訳ありません。
opyon

2018/08/31 09:12

解決済みになったようで良かったですね。 コード拝見してmapを入れ子にするところが参考になりました。 課題としてもとても勉強になりました。 ありがとうございます。 private static Map<String, String[]> map = new HashMap<>(); map.put("お", new String[] {"o"}); map.put("か", new String[] {"ka", "ca"});
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問