From 6e927e67477349de4cb41a8dc71f2bbb8ed2c5af Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Thu, 17 Apr 2025 10:27:14 +0300 Subject: [PATCH 1/4] Improved task 770 --- .../s0770_basic_calculator_iv/Solution.java | 300 +++++++++--------- 1 file changed, 144 insertions(+), 156 deletions(-) diff --git a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java index 15e2fb65c..126719b69 100644 --- a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java +++ b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java @@ -1,193 +1,181 @@ package g0701_0800.s0770_basic_calculator_iv; // #Hard #String #Hash_Table #Math #Stack #Recursion -// #2022_04_30_Time_8_ms_(96.92%)_Space_42.9_MB_(93.85%) +// #2025_04_17_Time_8_ms_(95.70%)_Space_45.18_MB_(49.46%) -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.TreeMap; public class Solution { - private static class Result { - private Map, Integer> map; + private String s; + private char[] arr; + private int[] braces; + private final Map variables = new HashMap<>(); - Result() { - map = new HashMap<>(); - } - - Result(Map, Integer> map) { - this.map = map; - } - - void update(List key, int val) { - map.put(key, map.getOrDefault(key, 0) + val); - } - - Map, Integer> getMap() { - return map; - } - - List toList() { - List> keyList = new ArrayList<>(map.keySet()); - Map, String> list2String = new HashMap<>(); - for (List key : keyList) { - StringBuilder sb = new StringBuilder(); - for (String k : key) { - sb.append(k).append("*"); - } - list2String.put(key, sb.toString()); + public List basicCalculatorIV(String expression, String[] evalvars, int[] evalints) { + s = expression; + arr = s.toCharArray(); + int n = arr.length; + braces = new int[n]; + Arrays.fill(braces, -1); + int[] stack = new int[n / 2]; + int index = -1; + for (int i = 0; i < n; ++i) { + if (arr[i] == '(') { + stack[++index] = i; + } else if (arr[i] == ')') { + int last = stack[index--]; + braces[last] = i; + braces[i] = last; } - keyList.sort( - (a, b) -> - (a.size() == b.size() - ? list2String.get(a).compareTo(list2String.get(b)) - : b.size() - a.size())); - List res = new ArrayList<>(); - for (List key : keyList) { - if (map.get(key) == 0) { - continue; - } - StringBuilder sb = new StringBuilder(); - sb.append(map.get(key)); - for (String k : key) { - sb.append("*").append(k); + } + for (int i = 0; i < evalvars.length; ++i) { + variables.put(evalvars[i], evalints[i]); + } + List terms = dewIt(0, n - 1); + Map map = + new TreeMap<>( + new Comparator<>() { + public int compare(String a, String b) { + int ca = countStars(a); + int cb = countStars(b); + if (ca != cb) { + return cb - ca; + } else { + return a.compareTo(b); + } + } + + private int countStars(String s) { + int ans = 0; + for (char c : s.toCharArray()) { + if (c == '*') { + ++ans; + } + } + return ans; + } + }); + for (Term term : terms) { + if (term.coeff != 0) { + String key = term.getKey(); + if (map.containsKey(key)) { + int oldCoeff = map.get(key); + if (oldCoeff == -term.coeff) { + map.remove(key); + } else { + map.put(key, oldCoeff + term.coeff); + } + } else { + map.put(key, term.coeff); } - res.add(sb.toString()); } - return res; } - } - - private Map evalMap; - private int i = 0; - - public List basicCalculatorIV(String expression, String[] evalvars, int[] evalints) { - evalMap = new HashMap<>(); - for (int j = 0; j < evalvars.length; j++) { - evalMap.put(evalvars[j], evalints[j]); + List ans = new LinkedList<>(); + for (String k : map.keySet()) { + ans.add(map.get(k) + k); } - i = -1; - next(expression); - Result res = expression(expression); - return res.toList(); + return ans; } - private Result expression(String s) { - Result res = term(s); - while (i < s.length() && (s.charAt(i) == '+' || s.charAt(i) == '-')) { - int c = s.charAt(i); - next(s); - if (c == '+') { - res = add(res, term(s)); + private List dewIt(int a, int b) { + if (braces[a] == b) { + return dewIt(a + 1, b - 1); + } + List ans = new LinkedList<>(); + List buffer = new LinkedList<>(); + buffer.add(new Term(1, new LinkedList<>())); + for (int i = a; i <= b; ) { + int j = i; + List curr; + if (arr[i] == '(') { + j = braces[i] + 1; + curr = dewIt(i + 1, j - 2); } else { - res = subtract(res, term(s)); + while (j <= b && arr[j] != ' ') { + ++j; + } + String exp = s.substring(i, j); + int val = 1; + List vars = new LinkedList<>(); + if (variables.containsKey(exp)) { + val = variables.get(exp); + } else if (exp.charAt(0) <= '9') { + val = Integer.parseInt(exp); + } else { + vars.add(exp); + } + curr = new LinkedList<>(); + curr.add(new Term(val, vars)); } + buffer = multiply(buffer, curr); + if (j > b || arr[j + 1] == '+' || arr[j + 1] == '-') { + ans.addAll(buffer); + buffer = new LinkedList<>(); + } + if (j < b) { + ++j; + if (arr[j] == '+') { + buffer.add(new Term(1, new LinkedList<>())); + } else if (arr[j] == '-') { + buffer.add(new Term(-1, new LinkedList<>())); + } + j += 2; + } + i = j; } - return res; - } - - private Result term(String s) { - Result res = factor(s); - while (i < s.length() && s.charAt(i) == '*') { - next(s); - res = multiply(res, factor(s)); - } - return res; + return ans; } - private Result multiply(Result r1, Result r2) { - Map, Integer> map1 = r1.getMap(); - Map, Integer> map2 = r2.getMap(); - Map, Integer> map = new HashMap<>(); - for (Map.Entry, Integer> entry1 : map1.entrySet()) { - for (Map.Entry, Integer> entry2 : map2.entrySet()) { - List key = new ArrayList<>(entry1.getKey()); - key.addAll(entry2.getKey()); - Collections.sort(key); - map.put(key, map.getOrDefault(key, 0) + entry1.getValue() * entry2.getValue()); + private List multiply(List a, List b) { + List ans = new LinkedList<>(); + for (Term x : a) { + for (Term y : b) { + Term prod = x.clone(); + prod.multiply(y); + ans.add(prod); } } - return new Result(map); + return ans; } - private Result add(Result r1, Result r2) { - Map, Integer> map1 = r1.getMap(); - Map, Integer> map2 = r2.getMap(); - Map, Integer> map = new HashMap<>(); - for (Map.Entry, Integer> entry1 : map1.entrySet()) { - map.put(entry1.getKey(), map.getOrDefault(entry1.getKey(), 0) + entry1.getValue()); - } - for (Map.Entry, Integer> entry2 : map2.entrySet()) { - map.put(entry2.getKey(), map.getOrDefault(entry2.getKey(), 0) + entry2.getValue()); - } - return new Result(map); - } + private static class Term { + int coeff; + List vars; - private Result subtract(Result r1, Result r2) { - Map, Integer> map1 = r1.getMap(); - Map, Integer> map2 = r2.getMap(); - Map, Integer> map = new HashMap<>(); - for (Map.Entry, Integer> entry1 : map1.entrySet()) { - map.put(entry1.getKey(), map.getOrDefault(entry1.getKey(), 0) + entry1.getValue()); - } - for (Map.Entry, Integer> entry2 : map2.entrySet()) { - map.put(entry2.getKey(), map.getOrDefault(entry2.getKey(), 0) - entry2.getValue()); + public Term(int a, List c) { + this.coeff = a; + vars = new LinkedList<>(); + vars.addAll(c); } - return new Result(map); - } - private Result factor(String s) { - Result res = new Result(); - if (s.charAt(i) == '(') { - next(s); - res = expression(s); - next(s); - return res; - } - if (Character.isLowerCase(s.charAt(i))) { - return identifier(s); + public String getKey() { + StringBuilder b = new StringBuilder(); + Collections.sort(vars); + for (String x : vars) { + b.append('*'); + b.append(x); + } + return b.toString(); } - res.update(new ArrayList<>(), number(s)); - return res; - } - private Result identifier(String s) { - Result res = new Result(); - StringBuilder sb = new StringBuilder(); - while (i < s.length() && Character.isLowerCase(s.charAt(i))) { - sb.append(s.charAt(i)); - i++; - } - i--; - next(s); - String variable = sb.toString(); - if (evalMap.containsKey(variable)) { - res.update(new ArrayList<>(), evalMap.get(variable)); - } else { - List key = new ArrayList<>(); - key.add(variable); - res.update(key, 1); - } - return res; - } - - private int number(String s) { - int res = 0; - while (i < s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9') { - res = res * 10 + (s.charAt(i) - '0'); - i++; + public void multiply(Term that) { + this.coeff *= that.coeff; + if (this.coeff == 0) { + vars.clear(); + } else { + this.vars.addAll(that.vars); + } } - i--; - next(s); - return res; - } - private void next(String s) { - i++; - while (i < s.length() && s.charAt(i) == ' ') { - i++; + public Term clone() { + return new Term(coeff, vars); } } } From f349a663e1fa2651493f25428929c6bef09c255f Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Thu, 17 Apr 2025 10:34:01 +0300 Subject: [PATCH 2/4] Replaced LinkedList with ArrayList --- .../s0770_basic_calculator_iv/Solution.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java index 126719b69..c2e98ed1f 100644 --- a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java +++ b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java @@ -3,11 +3,11 @@ // #Hard #String #Hash_Table #Math #Stack #Recursion // #2025_04_17_Time_8_ms_(95.70%)_Space_45.18_MB_(49.46%) +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -77,7 +77,7 @@ private int countStars(String s) { } } } - List ans = new LinkedList<>(); + List ans = new ArrayList<>(); for (String k : map.keySet()) { ans.add(map.get(k) + k); } @@ -88,9 +88,9 @@ private List dewIt(int a, int b) { if (braces[a] == b) { return dewIt(a + 1, b - 1); } - List ans = new LinkedList<>(); - List buffer = new LinkedList<>(); - buffer.add(new Term(1, new LinkedList<>())); + List ans = new ArrayList<>(); + List buffer = new ArrayList<>(); + buffer.add(new Term(1, new ArrayList<>())); for (int i = a; i <= b; ) { int j = i; List curr; @@ -103,7 +103,7 @@ private List dewIt(int a, int b) { } String exp = s.substring(i, j); int val = 1; - List vars = new LinkedList<>(); + List vars = new ArrayList<>(); if (variables.containsKey(exp)) { val = variables.get(exp); } else if (exp.charAt(0) <= '9') { @@ -111,20 +111,20 @@ private List dewIt(int a, int b) { } else { vars.add(exp); } - curr = new LinkedList<>(); + curr = new ArrayList<>(); curr.add(new Term(val, vars)); } buffer = multiply(buffer, curr); if (j > b || arr[j + 1] == '+' || arr[j + 1] == '-') { ans.addAll(buffer); - buffer = new LinkedList<>(); + buffer = new ArrayList<>(); } if (j < b) { ++j; if (arr[j] == '+') { - buffer.add(new Term(1, new LinkedList<>())); + buffer.add(new Term(1, new ArrayList<>())); } else if (arr[j] == '-') { - buffer.add(new Term(-1, new LinkedList<>())); + buffer.add(new Term(-1, new ArrayList<>())); } j += 2; } @@ -134,7 +134,7 @@ private List dewIt(int a, int b) { } private List multiply(List a, List b) { - List ans = new LinkedList<>(); + List ans = new ArrayList<>(); for (Term x : a) { for (Term y : b) { Term prod = x.clone(); @@ -151,7 +151,7 @@ private static class Term { public Term(int a, List c) { this.coeff = a; - vars = new LinkedList<>(); + vars = new ArrayList<>(); vars.addAll(c); } From f165fff29a12ad592a7b6a96871d27db61960a5e Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Thu, 17 Apr 2025 10:37:56 +0300 Subject: [PATCH 3/4] Fixed sonar --- .../g0701_0800/s0770_basic_calculator_iv/Solution.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java index c2e98ed1f..b9c730b7f 100644 --- a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java +++ b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java @@ -78,8 +78,8 @@ private int countStars(String s) { } } List ans = new ArrayList<>(); - for (String k : map.keySet()) { - ans.add(map.get(k) + k); + for (Map.Entry entry : map.entrySet()) { + ans.add(entry.getValue() + entry.getKey()); } return ans; } @@ -137,7 +137,7 @@ private List multiply(List a, List b) { List ans = new ArrayList<>(); for (Term x : a) { for (Term y : b) { - Term prod = x.clone(); + Term prod = x.copy(); prod.multiply(y); ans.add(prod); } @@ -174,7 +174,7 @@ public void multiply(Term that) { } } - public Term clone() { + public Term copy() { return new Term(coeff, vars); } } From c206f764d429cf752bda68be3d4af08a87a89323 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Thu, 17 Apr 2025 10:49:45 +0300 Subject: [PATCH 4/4] Fixed sonar --- .../java/g0701_0800/s0770_basic_calculator_iv/Solution.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java index b9c730b7f..03fd947c5 100644 --- a/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java +++ b/src/main/java/g0701_0800/s0770_basic_calculator_iv/Solution.java @@ -91,7 +91,8 @@ private List dewIt(int a, int b) { List ans = new ArrayList<>(); List buffer = new ArrayList<>(); buffer.add(new Term(1, new ArrayList<>())); - for (int i = a; i <= b; ) { + int i = a; + while (i <= b) { int j = i; List curr; if (arr[i] == '(') {