[ Java練習問題 ] 練習問題 第23回 『高難易度②』

目次

高難度問題

Java練習問題 第23回では前回に引き続き高難易度の問題を出題します。
前回の高難易度問題はこちら

問題 1 難易度 ★★★★★

入力された自然数を漢数字に変換して表示するプログラムを作成してください。

実行例

1 以上、9999 京未満の自然数を入力してください。
99980000000000000000
九千九百九十八京

1 以上、9999 京未満の自然数を入力してください。
10


1 以上、9999 京未満の自然数を入力してください。
10000
一万

1 以上、9999 京未満の自然数を入力してください。
10203040506070
十兆二千三十億四千五十万六千七十

1 以上、9999 京未満の自然数を入力してください。
111111111
一億千百十一万千百十一

1 以上、9999 京未満の自然数を入力してください。
100


1 以上、9999 京未満の自然数を入力してください。
121314151617
千二百十三億千四百十五万千六百十七

1 以上、9999 京未満の自然数を入力してください。
1000000000000
一兆

問題 1 解答

正解は、、、
public class Main_1901 {
  public static void main(String[] args) {
    while (true) {
      System.out.println("1 以上、9999 京未満の自然数を入力してください。");
      String str = new java.util.Scanner(System.in).nextLine();
      String res = convert(str);
      System.out.println(res);
      System.out.println();
    }
  }
  
  public static String convert(String str) {
    String[] numStrs = { "", "", "", "", "", "", "", "", "", "" };
    String[] numSmallUnits = { "", "", "", "" };
    String[] numLargeUnits = { "", "", "", "", "" };
    String res = "";
    for (int i = 0; i < str.length(); i++) {
      //数字文字列を末尾から見ていく
      char c = str.charAt(str.length() - 1 - i);
      int n = Integer.parseInt(c + "");
      if (i % numSmallUnits.length == 0) {
        //一万、一億、一兆、一京の桁の場合の処理
        res = removePrefix(res, numLargeUnits);
        res = numLargeUnits[(i) / numSmallUnits.length] + res;
      }
      //漢数字変換処理に"零"は不要
      if (n != 0) {
        res = numSmallUnits[i % numSmallUnits.length] + res;
        //一万、一億、一兆の表現はあるが、一千、一百、一十という表現はない。
        if (n != 1 || i % numSmallUnits.length == 0) {
          res = numStrs[n] + res;
        }
      }
    }
    return res;
  }
  
  public static String removePrefix(String str, String[] prefixAry) {
    if (str.length() < 1) {
      return str;
    }
    String res = "";
    //先頭文字が、"万", "億", "兆", "京"のいずれかならば、先頭文字を消去
    for (int i = 0; i < prefixAry.length; i++) {
      if ((String.valueOf(str.charAt(0)).equals(prefixAry[i]))) {
        res = str.replace(prefixAry[i], "");
        return res;
      }
    }
    return str;
  }
}

問題 2 難易度 ★★★★★

入力された漢数字を数字に変換して表示するプログラムを作成してください。
入力に使用される文字は、以下の 15 種類とします。
‘一’,’二’,’三’,’四’,’五’,’六’,’七’,’八’,’九’,’十’,’百’,’千’,’万’,’億’,’兆’

実行例

数値を漢数字で入力してください。
三兆八千二百八十五億百八十二万二千
3828501822000

数値を漢数字で入力してください。
十兆千十
10000000001010

数値を漢数字で入力してください。
十兆千十万
10000010100000

数値を漢数字で入力してください。
千百十一億千百十一万千百十一
111111111111

数値を漢数字で入力してください。

1

数値を漢数字で入力してください。
三億
300000000

数値を漢数字で入力してください。
四万百七十五
40175

数値を漢数字で入力してください。
三十九兆八千七百二十五億二千三百六十八万七千四百六十七
39872523687467

数値を漢数字で入力してください。

100

問題 2 解答

正解は、、、
public class Main_1902 {
  public static void main(String[] args) {
    while (true) {
      System.out.println("数値を漢数字で入力してください。");
      String str = new java.util.Scanner(System.in).nextLine();
      long num = convert(str);
      System.out.println(num);
      System.out.println();
    }
  }
  
  public static long convert(String str) {
    char[] jaNum = { ' ', '', '', '', '', '', '', '', '', '' };
    String[] units1 = { "", "", "" };
    String[] units2 = { "", "", "" };
    
    int[][] resultAry = new int[units1.length + 1][units2.length + 1];
  
    String[] ary = split(str, units1);
    for (int i = 0; i < ary.length; i++) {
      String[] ary2 = split(ary[i], units2);
      for (int j = 0; j < ary2.length; j++) {
        int n = 0;
        if (ary2[j] == null) {
          n = 0;
        } else if (ary2[j].equals("")) {
          n = 1;
        } else {
          char c = ary2[j].charAt(0);
          for (int k = 0; k < jaNum.length; k++) {
            if (c == jaNum[k]) {
              n = k;
            }
          }
        }
        resultAry[i][j] = n;
      }
    }
    
    long[] nums = { 1000000000000l, 100000000l, 10000l, 1l };
    long sum = 0;
    for (int i = 0; i < resultAry.length; i++) {
      String s = "";
      for (int j = 0; j < resultAry[i].length; j++) {
        s += resultAry[i][j];
      }
      sum += Long.parseLong(s) * nums[i];
    }
    return sum;
  }
  
  public static String[] split(String str, String[] delimiters) {
    String[] smallUnits = new String[delimiters.length + 1];
    if (str != null && !str.equals("")) {
      for (int i = 0; i < delimiters.length; i++) {
        if (str.contains(delimiters[i])) {
          String[] ary = str.split(delimiters[i]);
          
          if (ary.length == 0) {
          smallUnits[i] = "";
          }
          if (ary.length > 0) {
          smallUnits[i] = ary[0];
          }
          if (ary.length > 1) {
          str = ary[1];
          }
        }
      }
      if (!hasString(delimiters, str)) {
        smallUnits[smallUnits.length - 1] = str;
      }
    }
    return smallUnits;
  }
  
  public static boolean hasString(String[] ary, String str) {
    for (int i = 0; i < ary.length; i++) {
      if (str.contains(ary[i])) {
        return true;
      }
    }
  return false;
  }
}

問題 3 難易度 ★★★★

Calendar クラスの詳細を API リファレンスで確認して、
以下のようなカレンダー表示プログラムを完成させてください。

実行例

年を西暦で入力してください
2019
月を整数で入力してください
5
2019 年 5 月
sun mon tue wed thu fri sat
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

問題 3 解答

正解は、、、
import java.util.Calendar;
import java.util.Scanner;

public class Main_1903 {
  public static void main(String[] args) {
    System.out.println("年を西暦で入力してください");
    int year = new Scanner(System.in).nextInt();
    System.out.println("月を整数で入力してください");
    int month = new Scanner(System.in).nextInt() - 1;
    
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DATE, 1);
    System.out.println();
    System.out.println(year + "" + (month + 1) + "");
    System.out.print("sun mon tue wed thu fri sat");
    
    int startWeek = cal.get(Calendar.DAY_OF_WEEK);
    int endDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    for (int i = 0; i < startWeek + endDay; i++) {
      if (i < startWeek) {
        System.out.print(" ");
      } else {
        int date = i - startWeek + 1;
        if (date < 10) {
          System.out.print(" ");
        }
        System.out.print(" " + date + " ");
      }
      if (i % 7 == 0) {
        System.out.println();
      }
    }
  }
}

問題 4 難易度 ★★★★★

ユーザーの入力した整数を「■」の並びにして表示するプログラムを作成してください。

実行例

数値を入力してください。
256
横幅の倍率を入力してください
1
高さの倍率を入力してください。
1
□■■■□■■■□■■■
□□□■□■□□□■□□
□■■■□■■■□■■■
□■□□□□□■□■□■
□■■■□■■■□■■■
数値を入力してください。
4649
横幅の倍率を入力してください。
2
高さの倍率を入力してください。
2
□□■■□□■■□□■■■■■■□□■■□□■■□□■■■■■■
□□■■□□■■□□■■■■■■□□■■□□■■□□■■■■■■
□□■■□□■■□□■■□□□□□□■■□□■■□□■■□□■■
□□■■□□■■□□■■□□□□□□■■□□■■□□■■□□■■
□□■■■■■■□□■■■■■■□□■■■■■■□□■■■■■■
□□■■■■■■□□■■■■■■□□■■■■■■□□■■■■■■
□□□□□□■■□□■■□□■■□□□□□□■■□□□□□□■■
□□□□□□■■□□■■□□■■□□□□□□■■□□□□□□■■
□□□□□□■■□□■■■■■■□□□□□□■■□□■■■■■■
□□□□□□■■□□■■■■■■□□□□□□■■□□■■■■■■

問題 4 解答

正解は、、、
import java.util.Scanner;

public class Main_1904 {
  public static void main(String[] args) {
    while (true) {
      System.out.println("数値を入力してください。");
      String s = new Scanner(System.in).nextLine();
      System.out.println("横幅の倍率を入力してください。");
      int xScale = new Scanner(System.in).nextInt();
      System.out.println("高さの倍率を入力してください。");
      int yScale = new Scanner(System.in).nextInt();
      
      DotPrinter dotPrinter = new DotPrinter();
      dotPrinter.setXScale(xScale);
      dotPrinter.setYScale(yScale);
      dotPrinter.print(s);
      System.out.println();
    }
  }
}

class DotPrinter {
  private String[][][] fonts = new String[][][] { //
    { // 0
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 1
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 2
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 3
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 4
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 5
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
      { // 6
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 7
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 8
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, },
    { // 9
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, //
      { "", "", "", "" }, }, };
      
  private int xScale;
  private int yScale;
  
  public DotPrinter() {
    xScale = 1;
    yScale = 1;
  }
  
  public DotPrinter(int xScale, int yScale) {
    this.xScale = xScale;
    this.yScale = yScale;
  }
  
  public void setXScale(int xScale) {
    this.xScale = xScale;
  }
  
  public void setYScale(int yScale) {
    this.yScale = yScale;
  }
  
  public void print(String s) {
    //標準フォント一文字分の行数を繰り返す
    for (int i = 0; i < fonts[0].length; i++) {
      //高さの倍率に応じた繰り返し
      for (int j = 0; j < yScale; j++) {
        //出力文字数の繰り返し
        for (int k = 0; k < s.length(); k++) {
          //k 番目の文字を int 型に変換
          int num = Integer.valueOf(s.charAt(k) + "");
          //num(出力したい文字)の i 行目を横幅の倍率に応じて出力
          for (int l = 0; l < fonts[num][i].length; l++) {
            for (int m = 0; m < xScale; m++) {
              // try { /// 印刷機っぽく出力してみる
              // Thread.sleep(10);
              // } catch (InterruptedException e) {
              // e.printStackTrace();
              // }
              System.out.print(fonts[num][i][l]);
            }
          }
        }
        System.out.println();
      }
    }
  }
}

問題 5 難易度 ★★★★★

入力された四則演算計算式の計算結果を出力するプログラムを作成してください。
ただし、入力に使用される文字は「0~9」の数字と「.」「+」「-」「*」「/」の 15 種類とします。
掛け算と割り算は、足し算、引き算より先に処理してください。
計算の項には負の数値や小数が入ることもあります。
計算結果の小数点以下が 0 の場合は、整数表示してください。
計算結果の浮動小数点誤差については、無視してかまいません。(例:0.1+0.2 =0.30000000000000004)

実行例

計算式を入力してください
12+3/4
2.75

計算式を入力してください
1+23+4
11

計算式を入力してください
-1+2-3/-4
0.5

計算式を入力してください
1+23-4/-5+6.7*8
61.4

問題 5 解答

正解は、、、
import java.util.ArrayList;
import java.util.Scanner;

public class Main_1905 {
  public static void main(String[] args) {
    while (true) {
      System.out.println("計算式を入力してください");
      String ex = new Scanner(System.in).nextLine();
      ex = ex.replace("*", " * ").replace("/", " / ").replace("+", " + ")
        .replace("-", " -");
      String[] ary = ex.split(" ");
      ArrayList<String> list = toList(ary);
      double result = Double.parseDouble(calc(list));
      if (result == (int) result) {
        System.out.println((int) result);
      } else {
        System.out.println(result);
      }
      System.out.println();
    }
  }
  
  public static String calc(ArrayList<String> list) {
    calc(list, "*", "/");
    calc(list, "+", "-");
    return list.get(0);
  }
  
  public static void calc(ArrayList<String> list, String operator1, String operator2) {
    while (list.contains(operator1) || list.contains(operator2)) {
      for (int i = 0; i < list.size() - 1; i++) {
        String s = list.get(i + 1);
        if (s.equals(operator1) || s.equals(operator2)) {
          String res = calc(list.get(i), s.charAt(0),
            list.get(i + 2));
          for (int j = 0; j < 3; j++) {
            list.remove(i);
          }
          list.add(i, res);
          break;
        }
      }
    }
  }
  
  public static ArrayList<String> toList(String[] ary) {
    ArrayList<String> list = new ArrayList<>();
    for (int i = 0; i < ary.length; i++) {
      if (!ary[i].equals("")) {
        list.add(ary[i]);
      } else {
        continue;
      }
      if ((i < ary.length - 1) && (isNumber(ary[i]))&& (isNumber(ary[i + 1]))) {
        list.add("+");
      }
    }
    return list;
  }
  
  public static boolean isNumber(String str) {
    try {
      Double.parseDouble(str);
      return true;
    } catch (NumberFormatException e) {
      return false;
    }
  }
  
  public static String calc(String operand1, char operator, String operand2) {
    String res;
    double d1 = Double.parseDouble(operand1);
    double d2 = Double.parseDouble(operand2);
    switch (operator) {
    case '+':
      res = String.valueOf(d1 + d2);
      break;
    case '-':
      res = String.valueOf(d1 - d2);
      break;
    case '*':
      res = String.valueOf(d1 * d2);
      break;
    case '/':
      res = String.valueOf(d1 / d2);
      break;
    default:
      res = null;
      break;
    }
    return res;
  }
}
(Visited 212 times, 1 visits today)
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次