【Java】確認問題4-2:アラビア数字をローマ数字に変換しよう

一つ前のページではナインゲームを作成しました。
今回は アラビア数字をローマ数字に変換するアプリ を作成していきましょう。
Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編
Lesson4:コレクション編
・Lesson4-1:ArrayListを理解しよう
・Lesson4-2:HashSetとTreeSetを理解しよう
・Lesson4-3:HashMapを理解しよう
・Lesson4-4:TreeMapを理解しよう
・確認問題4-☆1:ナインゲームを作ろう
・確認問題4-☆2:アラビア数字をローマ数字に変換 ◁今回はココ
Lesson5:クラス編
ローマ数字に変換する方法を理解しよう|アルゴリズムと実装手順

アラビア数字(1、2、3、…)をローマ数字(I、II、III、…)に変換するプログラムを作成しましょう。
このプログラムでは、ユーザーが入力したアラビア数字を対応するローマ数字に変換して出力します。
この問題の要件
以下の要件に従ってコードを完成させてください。
ArabicToRomanConverterクラスを作成し、アラビア数字をローマ数字に変換するconvertメソッドを実装すること。- ユーザーからアラビア数字(1から3999の間)を入力として受け取ること。
- アラビア数字をローマ数字に変換するメソッド
convertToRoman(int number)を作成すること。 - ローマ数字は以下のように対応します:
- 1 -> I
- 4 -> IV
- 5 -> V
- 9 -> IX
- 10 -> X
- 40 -> XL
- 50 -> L
- 90 -> XC
- 100 -> C
- 400 -> CD
- 500 -> D
- 900 -> CM
- 1000 -> M
ただし、以下のような実行結果となること。
アラビア数字を入力してください(1から3999の間): 1987 ローマ数字: MCMLXXXVII
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
1:Scannerクラスをインポート
2:TreeMapクラスをインポート
3:ArabicToRomanクラスの定義
□ mainメソッドの定義
□ □ Scannerオブジェクトscannerの初期化
□ □ 「アラビア数字を入力してください(1から3999の間)」と出力
□ □ ユーザーの入力を整数として読み取り、変数numberに代入
□ □ convertToRomanメソッドを呼び出し、変数numberをローマ数字に変換して変数romanNumeralに代入
□ □ 「ローマ数字: 」と変数romanNumeralの内容を出力
□ convertToRomanメソッドの定義
□ □ TreeMapオブジェクトromanMapを降順で初期化
□ □ romanMapにアラビア数字とローマ数字の対応を登録
□ □ StringBuilderオブジェクトromanNumeralの初期化
□ □ for-eachループでromanMapの各キーを反復処理
□ □ □ whileループでnumberがkey以上の間、ローマ数字を追加し、numberをkey分減算
□ □ romanNumeralの文字列を返す
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
import java.util.Scanner; import java.util.TreeMap; public class ArabicToRoman { // メインメソッド public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // ユーザーにアラビア数字を入力させる System.out.print("アラビア数字を入力してください(1から3999の間): "); int number = scanner.nextInt(); // 入力された数字をローマ数字に変換する /*【穴埋め問題1】 ここでconvertToRomanメソッドを呼び出し、変数numberをローマ数字に変換して変数romanNumeralに代入するコードを書いてください。 */ // 結果を出力する System.out.println("ローマ数字: " + romanNumeral); } // アラビア数字をローマ数字に変換するメソッド public static String convertToRoman(int number) { // ローマ数字の対応を降順で設定するTreeMapを作成 /*【穴埋め問題2】 ここでTreeMapを作成し、対応するアラビア数字とローマ数字を登録するコードを書いてください。 */ StringBuilder romanNumeral = new StringBuilder(); // ローマ数字の対応を繰り返し処理でチェックしながら変換する /*【穴埋め問題3】 ここでfor-eachループを使って、ローマ数字の対応を繰り返し処理し、numberがkey以上の間は対応するローマ数字を追加するコードを書いてください。 */ return romanNumeral.toString(); } }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
練習問題の解答と解説
この問題の正解コードとその解説は以下の通りです。
クリックして開いて確認してください。
- 正解コード
-
import java.util.Scanner; import java.util.TreeMap; public class ArabicToRoman { // メインメソッド public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // ユーザーにアラビア数字を入力させる System.out.print("アラビア数字を入力してください(1から3999の間): "); int number = scanner.nextInt(); // 入力された数字をローマ数字に変換する String romanNumeral = convertToRoman(number); // 結果を出力する System.out.println("ローマ数字: " + romanNumeral); } // アラビア数字をローマ数字に変換するメソッド public static String convertToRoman(int number) { // ローマ数字の対応を降順で設定するTreeMapを作成 TreeMap<Integer, String> romanMap = new TreeMap<>(java.util.Collections.reverseOrder()); romanMap.put(1000, "M"); romanMap.put(900, "CM"); romanMap.put(500, "D"); romanMap.put(400, "CD"); romanMap.put(100, "C"); romanMap.put(90, "XC"); romanMap.put(50, "L"); romanMap.put(40, "XL"); romanMap.put(10, "X"); romanMap.put(9, "IX"); romanMap.put(5, "V"); romanMap.put(4, "IV"); romanMap.put(1, "I"); StringBuilder romanNumeral = new StringBuilder(); // ローマ数字の対応を繰り返し処理でチェックしながら変換する for (int key : romanMap.keySet()) { while (number >= key) { romanNumeral.append(romanMap.get(key)); number -= key; } } return romanNumeral.toString(); } }
- 正解コードの解説
-
コードをブロックごとに分割して解説します。
必要なライブラリのインポート
import java.util.Scanner; import java.util.TreeMap;
まず
ScannerとTreeMapクラスをインポートしています。Scannerはユーザーからの入力を受け取るために使い、TreeMapはアラビア数字とローマ数字の対応を保存するために使います。ArabicToRomanクラスの定義とメインメソッドの作成public class ArabicToRoman { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);ここでクラス
ArabicToRomanが定義され、プログラムのエントリーポイントであるmainメソッドが始まります。Scanner scanner = new Scanner(System.in);でユーザーからの入力を受け取るscannerオブジェクトを作成しています。ユーザーからの入力
System.out.print("アラビア数字を入力してください(1から3999の間): "); int number = scanner.nextInt();この部分では
System.out.printを使ってメッセージを表示し、scanner.nextInt()でユーザーが入力した数字を読み取ります。入力された数字は変数
numberに保存されます。ローマ数字への変換と結果の表示
String romanNumeral = convertToRoman(number); System.out.println("ローマ数字: " + romanNumeral);ユーザーが入力した数字
numberをconvertToRomanメソッドでローマ数字に変換し、その結果をromanNumeralに保存します。最後に変換されたローマ数字を表示します。
convertToRomanメソッドの定義public static String convertToRoman(int number) { TreeMap<Integer, String> romanMap = new TreeMap<>(java.util.Collections.reverseOrder()); romanMap.put(1000, "M"); romanMap.put(900, "CM"); romanMap.put(500, "D"); romanMap.put(400, "CD"); romanMap.put(100, "C"); romanMap.put(90, "XC"); romanMap.put(50, "L"); romanMap.put(40, "XL"); romanMap.put(10, "X"); romanMap.put(9, "IX"); romanMap.put(5, "V"); romanMap.put(4, "IV"); romanMap.put(1, "I");convertToRomanメソッドはアラビア数字をローマ数字に変換するためのメソッドです。まず
TreeMapオブジェクトromanMapを逆順(降順)に初期化し、キーにアラビア数字、値にローマ数字の対応を登録しています。これにより数字の大きい順に変換を行えるようにしています。
数値の変換処理
StringBuilder romanNumeral = new StringBuilder(); for (int key : romanMap.keySet()) { while (number >= key) { romanNumeral.append(romanMap.get(key)); number -= key; } } return romanNumeral.toString();StringBuilderオブジェクトromanNumeralを使って、ローマ数字を生成します。for-eachループでromanMapの各キー(アラビア数字)を順番に取り出し、whileループで入力値numberがそのキー以上であれば、その分のローマ数字を追加してnumberから引きます。これを繰り返すことで入力値に対応するローマ数字が完成します。


