[標準アルゴリズム]失われたカッコ


ソース
Baek Jun-失われたカッコ

🔎 質問する


ポテンシャル俊は正数と+,−と括弧で式を構成した.そして勢俊はかっこを全部削除した.
そして勢俊適はかっこをつけて、この式の値を最小限に抑えようとした.
この式の値を最小にするプログラムを適切なかっこで書いてください.

🚫 入力と出力


<入力>
最初の行には数式があります.式は「0」~「9」、「+」、「-」で構成され、最初の文字と最後の文字は数値です.また、2つ以上の演算子が連続して現れず、5桁よりずっと連続した数値はありません.数はゼロから始まることができます.入力式の長さは50以下です.
<出力>
1行目に正解を出力します.

💻 I/O例



📄🤔 コードと解釈プロセス


🔹 1番

import java.util.Scanner;

public class BaekJoon1541 {

	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
		String input = scanner.nextLine();

		int sum = 0;
		int tempSum = 0;
		String[] arr = input.split("\\-");
		String[] temp = arr[0].split("\\+");
		if(temp.length != 1) { //첫 기호가 +일때
			for (int i = 0; i < temp.length; i++) {
				sum+=Integer.parseInt(temp[i]);
			}
		}else {						//첫 기호가 -일때
			sum = Integer.parseInt(temp[0]);
		}
		for (int i = 1; i < arr.length; i++) {
			temp = arr[i].split("\\+");
			if(temp.length != 1) { //+기호가 있을 때
				for (int k = 0; k < temp.length; k++) {
					tempSum += Integer.parseInt(temp[k]);
				}
				sum -= tempSum;
				tempSum=0;
			}else {						//+기호가 없을 때
				sum -= Integer.parseInt(temp[0]);
			}
		}
		System.out.println(sum);
	}
}

🔸 1号解


最初のコードは
まず、演算子「-」を区切り文字に分割します.
分割後の最初の要素の計算式の値を計算します.
sumに保存します.
最初に連続して現れる演算子「+」は、より少ない結果値を生成するために使用できません.
最初の「-」演算子が表示される前に、前の数値をすべて加算します.
最初の演算子「-」が表示されてから、
演算子「+」によって結果値が大きくならないことを確認します.
演算子「+」で接続された数値にかっこを付けます.
演算子「-」は、結果値から減算されます.
例:
11+50-20+30+40-10+20-10
入力値が
11+50-(20+30+40)-(10+20)-10
演算子「+」で始まる数字を括弧で囲むと、
最初の「-」演算子の後、結果値を無条件に減らします.
これらの論理を実装し、通過した.
メモリ12840 KB/処理時間108 ms.

🔹 2番

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BaekJoon1541 {

public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String input = br.readLine();

		int sum = 0;
		String[] arr = input.split("\\-");
		String[] temp = arr[0].split("\\+");

		if(temp.length != 1) {
			for (int i = 0; i < temp.length; i++) {
				sum+=Integer.parseInt(temp[i]);
			}
		}else {
			sum = Integer.parseInt(temp[0]);
		}
		
		for (int i = 1; i < arr.length; i++) {
			temp = arr[i].split("\\+");
			if(temp.length != 1) {
				for (int k = 0; k < temp.length; k++) {
					sum -= Integer.parseInt(temp[k]);
				}
			}else {
				sum -= Integer.parseInt(temp[0]);
			}
		}
		System.out.println(sum);
	}
}

🔸 第二題


アルゴリズムの問題をできるだけ多くの方法で解決した後.
もっと勉強するために、他人のコードを見ます.
多くの人がScannerではなく入力を受信しています.BufferedReaderです.
今まで、Scannerの方が便利だと思っていたし、BufferedReaderよりもスピードが速いので、Scannerを使っていました.
しかし、みんながBufferedReaderを使っているのを見て、不思議に思って、あちこち探していたが、彼らには間違った知識があることに気づいた.
スキャナのバッファは1024文字
BufferedReaderには8192文字のバッファがあります.
入力データ量が多い場合、バッファの大きいBufferedReaderの方が有利です.
Scannerは様々な方法をサポートし、区切り記号でグループ化することができます.
入力値を正規表現としてチェックすると、不要な処理時間が増加します.
BufferedReaderは入力値をチェックする必要がなくString形式を受け入れるため、Scannerよりも処理速度が速い.
それぞれのメリットとデメリットがあるので必ずBufferedReaderを使います!違うから.
場合によってはどちらを使うか考えるべきです.
メモリ11508 KB/処理時間76ミリ秒.
1番のようにScannerを使用した場合に比べて処理時間が32 ms減少した.

🔹 3番

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BaekJoon1541 {

public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String input = br.readLine();

		int result = 0;
		String[] arr = input.split("\\-");
		String[] temp = arr[0].split("\\+");


		for (int i = 0; i < temp.length; i++) {
			result+=Integer.parseInt(temp[i]);
		}

		for (int i = 1; i < arr.length; i++) {
			temp = arr[i].split("\\+");
				for (int k = 0; k < temp.length; k++) {
					result -= Integer.parseInt(temp[k]);
				}
		}
		System.out.println(result);
	}
}

🔸 第三題


2番の方法をやり遂げて、処理時間を減らしました!明日の朝から忙しくて、そろそろ寝ます~
ベッドに横になった瞬間、頭をよぎる考えがあった.
「考えてみましたが、条件によって九余演算子を処理する必要はありますか?」
「条件文を削除すると、演算子'+'または'-'は同じfor文で処理されるのではないでしょうか...?」
すぐに布団を蹴り出し、演算子で区切られたif-elseドアを全部消して論理を再チェックしました.全く問題ありません.結果も当然通過した.
最初の問題を解く前に、演算子によって条件解を分けます.
そう考えて、やっと解けて、また髪の毛がこわばってしまったようです.
条件文に出会った回数はそれほど多くない.
メモリ11560 KB/処理時間80 ms、速度は2回とほぼ同じ.
不要な条件文が消え、コードがより簡潔になり、可読性が向上します.

😳❕ 感想&感想


このアルゴリズムを解いて得られた最大の収穫は,ScannerとBufferedReaderの違いを正確に理解することであるべきである.
Javaを習い始めたばかりの頃、Scannerはもっと便利で、間違った知識のため、Scannerはもっと速いと思っていたので、ずっとScannerだけを使っていました.
しかし、私はこのアルゴリズムを解いたとき、これは間違った知識であることに気づいた.
今後はBufferedReaderを多用したいと思います
また,3回の経験を通して,不必要な論理を自然に含んでいるかどうかに疑問を抱かなければならない.
もちろん必要だと思います.
よく考えてみると、まったく必要ありません.
こんなことは二度と起こらない.
彼はまだ新しい開発者だからだ.
最初のコードから効率的なコードを記述することはできません.
私はすべての努力を惜しまず改善し、より効率的なコードを作成しようとする開発者になりたいと思っています.