PTAにJavaコードを提出する際のベストプラクティス

PTAにおけるJavaプログラム提出時の注意点

0. package宣言を含めない

提出するすべてのコードは、packageキーワードを絶対に含んではいけません。これがあるとコンパイルエラーになります。

1. Mainクラスと入力処理

1.1 入口となるMainクラス

提出するコードは必ず以下の構造にしてください:
public class Main {
    public static void main(String[] args) {
        // 実装内容
    }
}
- クラス名はMainでなければなりません。 - public修飾子を持つのはこのクラスのみです。他のクラスはpublicにしないでください。

1.2 入力の読み取り(Scannerの使い方)

標準入力からデータを読み取るにはjava.util.Scannerを使います。基本的な手順は次の通りです:
  • 先頭にimport java.util.Scanner;を追加。
  • Scanner in = new Scanner(System.in);でインスタンスを作成。
Scannerは文字列に対しても使用可能です:
String input = "100 hello 3.14";
Scanner parser = new Scanner(input);
int num = parser.nextInt();     // 100
String word = parser.next();    // "hello"
double pi = parser.nextDouble(); // 3.14
例1:整数のペアを繰り返し読み込んで和を出力
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a + b);
        }
        in.close();
    }
}
例2:"end"が入力されるまで1行ずつ出力
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String line;
        while (!(line = in.nextLine()).equals("end")) {
            System.out.println(line);
        }
        in.close();
    }
}
例3:n件のデータを読み込む
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for (int i = 0; i < n; i++) {
            String name = in.next();
            int age = in.nextInt();
            // 処理を行う
        }
        in.close();
    }
}

区切り文字について:
next()系メソッドはスペース、タブ、改行を区切りとして扱います。

2. Scannerの主なメソッド

メソッド説明
hasNext()次のトークンが存在するか(文字列)
next()次のトークンを文字列で取得
hasNextInt()次のトークンが整数として解釈可能か
nextInt()次のトークンをint型として取得
nextDouble()次のトークンをdouble型として取得
nextLine()現在位置から改行までを1行として取得(改行を消費)

3. 型変換の基本パターン

// 文字列 → 数値
String s = "123";
int val = Integer.parseInt(s);
double d = Double.parseDouble("3.14");

// 数値 → 文字列
int count = 42;
String str = String.valueOf(count); // 方法1
String str2 = "" + count;           // 方法2
String str3 = Integer.toString(count); // 方法3

4. 出力方法

4.1 改行付き出力

System.out.println("Hello"); // 出力後に改行
System.out.println(123 + "円"); // 数値と連結可能

4.2 改行なし出力

System.out.print("No newline ");

4.3 書式化出力(printf)

System.out.printf("%d, %.2f, %s%n", 100, 3.1415, "text");
// 出力: 100, 3.14, text
  • %d: 整数
  • %.2f: 小数点以下2桁の浮動小数点数
  • %s: 文字列
  • %n: 改行
  • %%: パーセント記号そのもの

5. 可変長データの保持方法

5.1 配列の動的生成

int n = in.nextInt();
int[] data = new int[n];
for (int i = 0; i < n; i++) {
    data[i] = in.nextInt();
}

5.2 ArrayListの利用

import java.util.ArrayList;
// ...
ArrayList<String> list = new ArrayList<>();
while (in.hasNextLine()) {
    String line = in.nextLine();
    if (line.equals("end")) break;
    list.add(line);
}

// 出力方法1:インデックス
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

// 出力方法2:拡張for文
for (String item : list) {
    System.out.println(item);
}

6. よくある問題と対策

6.1 コンパイルエラーになる

  • クラス名がMainではない
  • package文が含まれている
  • 複数のpublic classがある
  • コード中に日本語コメントや文字が含まれている
  • Java 9以降の構文を使っている(現状未サポート)

6.2 答えが合わない / 出力形式が違う

  • 出力末尾に改行が足りない
  • 余分な空白文字が含まれている
  • 半角・全角が混在している
  • サンプル入出力を左右に並べて比較しましょう

6.3 nextLine()とnextInt()の混在問題

nextInt()は改行をバッファに残すため、直後にnextLine()を使うと空文字列が取得されます。
int x = in.nextInt();
in.nextLine(); // ダミー呼び出しで改行を消費
String y = in.nextLine();
推奨される回避策:すべての入力をnextLine()で読み、必要に応じてInteger.parseInt()などで変換する。

6.4 Scannerの多重生成

ループ内で毎回new Scanner(System.in)するのは誤りです。
// 誤り
for (...) {
    Scanner in = new Scanner(System.in); // ×
}

// 正しい
Scanner in = new Scanner(System.in);
for (...) { ... }

6.5 無限ループからの脱出

ローカル実行時、無限ループに入った場合はCtrl + Z(Windows)またはCtrl + Cで中断できます。

6.6 複数クラスの定義方法

1つのファイルに複数のクラスを書けますが、publicMainクラスにのみ指定します。
class Student { /*...*/ }
class Course { /*...*/ }

public class Main {
    public static void main(String[] args) { /*...*/ }
}

6.7 大量データでタイムアウトする場合

Scannerは高速入力に向いていないため、大規模入力ではBufferedReaderを使用してください。
import java.io.BufferedReader;
import java.io.InputStreamReader;

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line = reader.readLine();
さらに高速化が必要ならStringTokenizerと組み合わせます:
import java.util.StringTokenizer;

StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
int first = Integer.parseInt(tokenizer.nextToken());

7. テスト効率化のヒント

  • 入力例をテキストファイルにコピー
  • 不要な空白行は削除
  • プログラム実行後、Ctrl+Vで一括貼り付け
  • 最終行の改行も含めてコピーすること

タグ: Java Scanner BufferedReader StringTokenizer PTA

5月20日 13:48 投稿