teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

スペルミス

2021/12/18 14:16

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -212,7 +212,7 @@
212
212
  : word.equals("*") || word.equals("/") ? Priority.HIGH
213
213
  : Priority.LOW;
214
214
  }
215
- void setPriotiry(Priority priority) { this.priority = priority; }
215
+ void setPriority(Priority priority) { this.priority = priority; }
216
216
  /**
217
217
  * 自分のほうが優先順位が高いと true
218
218
  */
@@ -271,7 +271,7 @@
271
271
  return true;
272
272
  }
273
273
  if(token.equals(")")) {
274
- root.setPriotiry(Node.Priority.NUMBER); //括弧部分は数値の優先度
274
+ root.setPriority(Node.Priority.NUMBER); //括弧部分は数値の優先度
275
275
  root = setNumberNode(stack.pop(), root);
276
276
  return true;
277
277
  }

2

若干最適化

2021/12/18 14:16

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -271,9 +271,8 @@
271
271
  return true;
272
272
  }
273
273
  if(token.equals(")")) {
274
- Node old = stack.pop();
275
274
  root.setPriotiry(Node.Priority.NUMBER); //括弧部分は数値の優先度
276
- if(old != null) root = setNumberNode(old, root);
275
+ root = setNumberNode(stack.pop(), root);
277
276
  return true;
278
277
  }
279
278
  return false;

1

コード追加

2021/12/18 13:33

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -179,4 +179,152 @@
179
179
  L:'1'
180
180
  R:null
181
181
  L:null
182
+ ```
183
+ ----
184
+ 括弧を処理できるようにして BinaryTree を (FormulaBinaryTree) オブジェクトとして復活させると以下の風になりました。
185
+ ```java
186
+ package teratail_java.q374212;
187
+
188
+ import java.util.*;
189
+ import java.util.regex.Pattern;
190
+
191
+ class Node {
192
+ public static enum Priority {
193
+ LOW, HIGH, NUMBER;
194
+ boolean over(Priority other) { return ordinal() > other.ordinal(); }
195
+ }
196
+ private static final Pattern NUM_PATTERN = Pattern.compile("[0123456789]+");
197
+
198
+ final String word;
199
+ Node right, left;
200
+ final boolean isNumber;
201
+ private Priority priority;
202
+
203
+ Node(String word) {
204
+ this(word, null, null);
205
+ }
206
+ Node(String word, Node left, Node right) {
207
+ this.word = word;
208
+ this.left = left;
209
+ this.right = right;
210
+ isNumber = NUM_PATTERN.matcher(word).matches();
211
+ priority = isNumber ? Priority.NUMBER
212
+ : word.equals("*") || word.equals("/") ? Priority.HIGH
213
+ : Priority.LOW;
214
+ }
215
+ void setPriotiry(Priority priority) { this.priority = priority; }
216
+ /**
217
+ * 自分のほうが優先順位が高いと true
218
+ */
219
+ boolean isPrioritize(Node other) { return priority.over(other.priority); }
220
+
221
+ void print() { print(""); }
222
+ void print(String indent) {
223
+ System.out.println("'"+word+"'");
224
+ printLink(indent, " R:", right);
225
+ printLink(indent, " L:", left);
226
+ }
227
+ private void printLink(String indent, String label, Node link) {
228
+ System.out.print(indent+label);
229
+ if(link == null) System.out.println("null");
230
+ else link.print(indent+" ");
231
+ }
232
+ }
233
+
234
+ class FormulaBinaryTree {
235
+ private Node root = null;
236
+
237
+ FormulaBinaryTree(String[] tokens) {
238
+ Deque<Node> stack = new LinkedList<>(); //null が入れられる必要がある為 ArrayDeque は不可
239
+ for(String token : tokens) {
240
+ if(doBrackets(token, stack)) continue;
241
+
242
+ Node node = new Node(token);
243
+ if(node.isNumber) {
244
+ root = setNumberNode(root, node);
245
+ } else if(node.isPrioritize(root)) { //演算子優先順位による入れ替え
246
+ node.left = root.right;
247
+ root.right = node;
248
+ } else {
249
+ node.left = root;
250
+ root = node;
251
+ }
252
+ }
253
+ }
254
+
255
+ private Node setNumberNode(Node root, Node node) {
256
+ if(root == null) return node; //(1つ目は数字のはず)
257
+ //右端へ
258
+ Node t = root;
259
+ while(t.right != null) t = t.right;
260
+ t.right = node;
261
+ return root;
262
+ }
263
+ /**
264
+ * 括弧処理
265
+ * こっそり括弧内を別ツリーとして生成を続けさせ、閉じ括弧で元のツリーに合成する
266
+ */
267
+ private boolean doBrackets(String token, Deque<Node> stack) {
268
+ if(token.equals("(")) {
269
+ stack.push(root);
270
+ root = null;
271
+ return true;
272
+ }
273
+ if(token.equals(")")) {
274
+ Node old = stack.pop();
275
+ root.setPriotiry(Node.Priority.NUMBER); //括弧部分は数値の優先度
276
+ if(old != null) root = setNumberNode(old, root);
277
+ return true;
278
+ }
279
+ return false;
280
+ }
281
+
282
+ //構造確認用
283
+ void print() {
284
+ System.out.print("root:");
285
+ root.print();
286
+ }
287
+ }
288
+
289
+ public class Step3 {
290
+ public static void main(String[] args){
291
+ String[] textm = input();//命令文入力
292
+
293
+ //中置記法を二分木にする
294
+ FormulaBinaryTree fbt = new FormulaBinaryTree(textm);
295
+
296
+ //確認
297
+ fbt.print();
298
+ }
299
+
300
+ private static String[] input() {
301
+ System.out.print("命令文入力:");
302
+ try(Scanner scan = new Scanner(System.in);) { //標準入力読み込み
303
+ String line = scan.nextLine();
304
+ return line.split(" ");//空白区切り
305
+ }
306
+ }
307
+ }
308
+ ```
309
+ ```plain
310
+ 命令文入力:( 1 + ( 2 - 3 * 4 ) ) / 5
311
+ root:'/'
312
+ R:'5'
313
+ R:null
314
+ L:null
315
+ L:'+'
316
+ R:'-'
317
+ R:'*'
318
+ R:'4'
319
+ R:null
320
+ L:null
321
+ L:'3'
322
+ R:null
323
+ L:null
324
+ L:'2'
325
+ R:null
326
+ L:null
327
+ L:'1'
328
+ R:null
329
+ L:null
182
330
  ```