こんにちは、Kuniです。現在Javaを学習中で、Atcoderでコーディング力を高めているところです。
そこで競プロ典型90問 004-CrossSumにおいて、TLEが続いてしまい詰まったので、共有します。
TLEのプログラムとACのプログラム
TLEとなってしまったプログラム
import java.util.*;
public class Main {
public static void main(String[] args){
//標準入力受け取り準備
Scanner scanner = new Scanner(System.in);
//Intで読み込み
int H = scanner.nextInt();
int W = scanner.nextInt();
//配列定義&格納
int[][] number = new int[H][W];
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
number[i][j] = scanner.nextInt();
}
}
scanner.close();
//行と列の合計値計算
int[] sum_line = new int[H];
int[] sum_row = new int[W];
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
sum_line[i] += number[i][j];
sum_row[j] += number[i][j];
}
}
//結果格納配列
int[][] result = new int[H][W];
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
result[i][j] = sum_line[i] + sum_row[j] - number[i][j];
System.out.printf("%d"+" ", result[i][j]);
}
System.out.printf("\n");
}
}
}
ACとなったプログラム
import java.util.Scanner;
public class Main { //クラス名はMain
public static void main(String[] args) {
//標準入力受け取り準備
Scanner scanner = new Scanner(System.in);
//Intで読み込み
int H = Integer.parseInt(scanner.next());
int W = Integer.parseInt(scanner.next());
//配列格納
int[][] number = new int[H][W];
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
number[i][j] = Integer.parseInt(scanner.next());
}
}
scanner.close();
//行と列の合計値計算
int[] sum_line = new int[H];
int[] sum_row = new int[W];
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
sum_line[i] += number[i][j];
sum_row[j] += number[i][j];
}
}
//結果格納配列
for(int i = 0; i < H; i++){
StringBuilder sb = new StringBuilder();
for(int j = 0; j < W; j++){
if(j != 0){
sb.append(" ");
}
sb.append(sum_line[i] + sum_row[j] - number[i][j]);
}
System.out.println(sb.toString());
}
}
}
TLEとなっていた原因
Javaでは、プログラムを実行するためにVMが存在しているそうですが、変数を保存するための宣言で値を保存しておくためのヒープを確保します。ループを使ってどんどんと値を入れていくような処理をすると、ヒープ領域が増えていってしまい、処理速度の低下に繋がるそうです。
TLEが発生していたプログラムはこのことが原因で処理速度が低下し、設定時間内にプログラムを終わらせることができませんでした。
そこでこの問題を解決するために利用するのが、StringBuilderクラスです。
StringBuilderクラスとは
このクラスは文字列操作を行うことができます。その中でString型はimmutableなオブジェクトですが、StringBuilderはmutableなオブジェクトで、元の文字列を書き換えることができます。今回の問題に対しては文字列を結合するために利用します。
プログラム内ではStringBuilderのインスタンスを生成し、appendメソッドを利用してインスタンス変数に値を追加します。最後の出力の際にはテキストとして出力を行っています。
参考になれば嬉しいです!!