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

記事内に商品プロモーションを含む場合があります

この記事の練習問題で使用する知識:
基礎文法(レッスン1)比較演算子と論理演算子if文による分岐処理when文による分岐処理for文による繰り返し処理while文による繰り返し処理関数の定義と呼出し関数の戻り値Mapコレクション操作

Kotlinのゲームコード一覧はこちら(準備中)

<<前のページ Kotlin記事一覧 次のページ>>

確認問題:アラビア数字をローマ数字に変換しよう

アラビア数字をローマ数字に変換するプログラムを作成しましょう。

このプログラムではユーザーにアラビア数字を入力してもらい、それをローマ数字に変換して表示します。変換にはローマ数字の基本的な対応表を使用します。

また、プログラムを分かりやすくするために、変換処理や入力処理を関数として分離してください。

この問題の要件

以下の要件に従ってプログラムを完成させてください。

  1. ローマ数字の対応表を定義すること。
    • arabicValues という配列に [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] を格納すること。
    • romanNumerals という配列に ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] を格納すること。
  2. アラビア数字をローマ数字に変換する関数 convertToRoman を作成すること。
    • この関数は引数にアラビア数字を受け取り、ローマ数字の文字列を返すこと。
  3. 入力を受け取る処理を processUserInput 関数として定義すること。
    • ユーザーが入力したアラビア数字を取得し、convertToRoman を使ってローマ数字に変換して表示すること。
  4. メイン関数ではprocessUserInput 関数を呼び出すだけにすること。

ただし、以下のような実行結果となること。

----- ↓出力される結果の例↓ -----

アラビア数字を入力してください: 1987
ローマ数字: MCMLXXXVII

アラビア数字を入力してください: abc
無効な数値です。
ローマ数字の表記ルール

基本記号とその値

ローマ数字は以下の記号とその値に基づいています:

  • I = 1
  • V = 5
  • X = 10
  • L = 50
  • C = 100
  • D = 500
  • M = 1000

記号の組み合わせ

  • 基本記号は、最大で3回まで繰り返して使用できます。

例: III = 3、XXX = 30、CCC = 300

  • 通常、ローマ数字は大きな値から小さな値へと左から右に書かれます。

例: MDCLXVI = 1666(1000 + 500 + 100 + 50 + 10 + 5 + 1)

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:ローマ数字の対応表を定義(変数arabicValuesとromanNumeralsを宣言)
  □ arabicValuesに整数の配列を代入
  □ romanNumeralsにローマ数字の文字列配列を代入
2:アラビア数字をローマ数字に変換する関数convertToRomanの定義
  □ 引数arabicを受け取り、戻り値が文字列型の関数
  □ 変数arabicを再定義
  □ StringBuilderオブジェクトromanを初期化
  □ for文でarabicValuesのインデックス範囲を繰り返し処理
  □ □ while文でarabicが現在のarabicValuesの値以上である間、処理を実行
  □ □ □ romanに対応するromanNumeralsの文字列を追加
  □ □ □ arabicからarabicValuesの値を減算
  □ romanを文字列に変換してreturnで返す
3:ユーザー入力を取得しローマ数字に変換して表示する関数processUserInputの定義
  □ ユーザーにアラビア数字の入力を促すメッセージをprint
  □ readLineで入力を取得し、Null安全性を考慮してtoIntOrNullで整数型に変換
  □ □ Nullまたは無効な値の場合、「無効な数値です。」を出力し処理を終了
  □ convertToRomanを呼び出してローマ数字に変換し、変数romanに代入
  □ 変換結果をprintで出力
4:メイン関数mainの定義
  □ processUserInputを呼び出す

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

// ローマ数字の対応表
val arabicValues = arrayOf(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
val romanNumerals = arrayOf("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I")

// アラビア数字をローマ数字に変換する関数
fun convertToRoman(arabic: Int): String {
    var arabic = arabic
    val roman = StringBuilder()

    /* 【穴埋め問題1】
    arabicValues 配列のインデックスをループし、arabic が対応する値以上の場合にローマ数字を追加し、arabic を減らす処理を書いてください。
    */
    
    return roman.toString()
}

// ユーザー入力を取得し、ローマ数字に変換して表示する関数
fun processUserInput() {
    print("アラビア数字を入力してください: ")
    val arabic = /* 【穴埋め問題2】
    readLine を使用してユーザー入力を取得し、整数に変換するコードを書いてください。数値に変換できない場合は適切な処理をしてください。
    */
    val roman = convertToRoman(arabic)
    println("ローマ数字: $roman")
}

// メイン関数
fun main() {
    /* 【穴埋め問題3】
    processUserInput 関数を呼び出して、プログラムを開始するコードを書いてください。
    */
}

この問題の穴埋めコードは以上です。

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

確認問題の解答と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

// ローマ数字の対応表
val arabicValues = arrayOf(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
val romanNumerals = arrayOf("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I")

// アラビア数字をローマ数字に変換する関数
fun convertToRoman(arabic: Int): String {
    var arabic = arabic
    val roman = StringBuilder()

    for (i in arabicValues.indices) {
        while (arabic >= arabicValues[i]) {
            roman.append(romanNumerals[i])
            arabic -= arabicValues[i]
        }
    }

    return roman.toString()
}

// ユーザー入力を取得し、ローマ数字に変換して表示する関数
fun processUserInput() {
    print("アラビア数字を入力してください: ")
    val arabic = readLine()?.toIntOrNull() ?: run {
        println("無効な数値です。")
        return
    }

    val roman = convertToRoman(arabic)
    println("ローマ数字: $roman")
}

// メイン関数
fun main() {
    processUserInput()
}

正解コードの解説

このプログラムはアラビア数字をローマ数字に変換する方法を学ぶためのシンプルなKotlinコードです。

以下にコードをブロックごとに分割し、各部分の解説を行います。

ローマ数字の対応表の定義

val arabicValues = arrayOf(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
val romanNumerals = arrayOf("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I")
  • arrayOf: Kotlinで配列を作成する際に使用します。
  • arabicValues はアラビア数字をローマ数字に変換する際の対応表です。
  • romanNumerals はローマ数字の対応表で、arabicValues と対応する順序で格納されています。

ローマ数字に変換する関数の定義

fun convertToRoman(arabic: Int): String {
    var arabic = arabic
    val roman = StringBuilder()

    for (i in arabicValues.indices) {
        while (arabic >= arabicValues[i]) {
            roman.append(romanNumerals[i])
            arabic -= arabicValues[i]
        }
    }

    return roman.toString()
}
  1. convertToRoman: アラビア数字をローマ数字に変換するための関数です。
    • arabic: Int: 入力として整数型のアラビア数字を受け取ります。
    • StringBuilder: 文字列を効率よく操作するためのクラスです。
  2. ループ処理:
    • for (i in arabicValues.indices): 配列のインデックスを繰り返し処理するループです。
    • while (arabic >= arabicValues[i]): 現在のアラビア数字が対応するローマ数字以上の場合、繰り返し文字列に追加し、値を引きます。

ユーザー入力を処理する関数

fun processUserInput() {
    print("アラビア数字を入力してください: ")
    val arabic = readLine()?.toIntOrNull() ?: run {
        println("無効な数値です。")
        return
    }

    val roman = convertToRoman(arabic)
    println("ローマ数字: $roman")
}
  • readLine(): コンソールからユーザーの入力を取得します。
  • toIntOrNull(): 入力値を整数に変換します。変換できない場合は null を返します。
  • エラーチェック:
    • ?: run: 入力が無効な場合にエラーメッセージを表示して処理を終了します。
  • convertToRoman の呼び出し: 入力値を変換して結果を表示します。

メイン関数

fun main() {
    processUserInput()
}
  • main: Kotlinプログラムのエントリーポイントです。
  • processUserInput の呼び出し: メイン関数では processUserInput を呼び出すだけで、プログラム全体を実行します。

まとめ

このプログラムでは関数を使ったコードの分離と、ループや条件分岐を使用した効率的な処理を学べます。特に以下のポイントが重要です

  1. 配列とループを活用してデータの対応関係を処理する方法。
  2. ユーザー入力のエラーチェックと処理。
  3. コードを関数で分割して読みやすく再利用可能にする設計。

Kotlinの基本的な構文や文法を体験し、応用するための第一歩としてこのコードを参考にぜひ挑戦してみてください!

<<前のページ Kotlin記事一覧 次のページ>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Kotlinテキスト&問題集へ戻る
    トップページへ戻る