Results 1 to 4 of 4
  1. #1
    Bronsonboy is offline Member
    Join Date
    Jun 2012
    Location
    Illinois
    Posts
    4
    Rep Power
    0

    Default replaceAll(string a, string b) not working as expected

    I have written a method designed to evaluate a string containing numbers and operators and return a string with the simplified result; however, it loops through the following section of code without changing the string variable to use the simplified value. I have included the full text of the java file below, as well as the test class and args I've been debugging with. Math2.java includes a number of System.out.println commands I placed there for debugging. Unfortunately, although all my other variables are what I expected them to be, the "expression" variable isn't being changed, causing the program to loop infinitely through this set of commands:
    Java Code:
    String result;
    while (expression.indexOf('^') != -1) {
        System.out.println("E");
        int operatorIndex = expression.indexOf('^');
        double[] nums = getNums(expression, operatorIndex);
        result = Double.toString(java.lang.Math.pow(nums[0], nums[1]));
        String original = expression.substring(begin1, end2);
        System.out.println(original + "->" + result);
        // the problem appears to be in the following statement
        expression = expression.replaceAll(original, result);
        System.out.println(expression);
    }
    Full Text of Math2.Java:
    Java Code:
    package myMods;
    /*
     * All System.out.prinln methods were inserted for debugging,
     * so I could follow the program flow better. The getNums method is at the
     * bottom. The statement giving me issues is at line 30.
     */
    public class Math2 {
        static int begin1; static int end1; static int begin2; static int end2;
        
        public static String simplify(String expression) {
            int begin = expression.lastIndexOf('(');
            int end = expression.indexOf(')', begin);
            while (begin != -1) {
                if (end == -1) end = expression.length();
                String subexpression = expression.substring(begin + 1, end - 1);
                String result = simplify(subexpression);
                expression.replaceAll(subexpression, result);
                System.out.println("P");
                System.out.println(expression);
            }
            String result;
            while (expression.indexOf('^') != -1) {
                System.out.println("E");
                int operatorIndex = expression.indexOf('^');
                double[] nums = getNums(expression, operatorIndex);
                result = Double.toString(java.lang.Math.pow(nums[0], nums[1]));
                String original = expression.substring(begin1, end2);
                System.out.println(original + "->" + result);
                // the problem appears to be in the following statement
                expression = expression.replaceAll(original, result);
                System.out.println(expression);
            }
            char op;
            while (expression.indexOf('*') != -1 || expression.indexOf('/') != -1) {
                int multiplyIndex = expression.indexOf('*');
                int divideIndex = expression.indexOf('/');
                int operatorIndex;
                if (multiplyIndex == -1) {
                    operatorIndex = divideIndex;
                    op = '/';
                } else if (divideIndex == -1) {
                    operatorIndex = multiplyIndex;
                    op = '*';
                } else {
                    operatorIndex = min(divideIndex, multiplyIndex);
                    op = min(divideIndex, multiplyIndex) == divideIndex ? '/' : '*';
                }
                double[] nums = getNums(expression, operatorIndex);
                if (op == '/') {
                    result = Double.toString(nums[0] / nums[1]);
                } else {
                    result = Double.toString(nums[0] * nums[1]);
                }
                String original = expression.substring(begin1, end2);
                expression.replaceAll(original, result);
                System.out.println("MD");
                System.out.println(expression);
            }
            while (expression.indexOf('+') != -1 || expression.indexOf('-') != -1) {
                int addIndex = expression.indexOf('+');
                int subtractIndex = expression.indexOf('-');
                int operatorIndex;
                if (addIndex == -1) {
                    operatorIndex = subtractIndex;
                    op = '-';
                } else if (subtractIndex == -1) {
                    operatorIndex = addIndex;
                    op = '+';
                } else {
                    operatorIndex = min(subtractIndex, addIndex);
                    op = min(subtractIndex, addIndex) == subtractIndex ? '-' : '+';
                }
                double[] nums = getNums(expression, operatorIndex);
                if (op == '-') {
                    result = Double.toString(nums[0] - nums[1]);
                } else {
                    result = Double.toString(nums[0] + nums[1]);
                }
                String original = expression.substring(begin1, end2);
                expression.replaceAll(original, result);
                System.out.println("AS");
                System.out.println(expression);
            }
            
            return expression;
        }
        
        public static int max(int... set) {
            int max = set[0];
            for (int i : set) {
                max = java.lang.Math.max(max, i);
            }
            return max;
        }
        
        public static long max(long... set) {
            long max = set[0];
            for (long i : set) {
                max = java.lang.Math.max(max, i);
            }
            return max;
        }
        
        public static float max(float... set) {
            float max = set[0];
            for (float i : set) {
                max = java.lang.Math.max(max, i);
            }
            return max;
        }
        
        public static double max(double... set) {
            double max = set[0];
            for (double i : set) {
                max = java.lang.Math.max(max, i);
            }
            return max;
        }
        
        public static int min(int... set) {
            int min = set[0];
            for (int i : set) {
                min = java.lang.Math.min(min, i);
            }
            return min;
        }
        
        public static long min(long... set) {
            long min = set[0];
            for (long i : set) {
                min = java.lang.Math.min(min, i);
            }
            return min;
        }
        
        public static float min(float... set) {
            float min = set[0];
            for (float i : set) {
                min = java.lang.Math.min(min, i);
            }
            return min;
        }
        
        public static double min(double... set) {
            double min = set[0];
            for (double i : set) {
                min = java.lang.Math.min(min, i);
            }
            return min;
        }
        
        private static double[] getNums(String expression, int operatorIndex) {
            begin1 = operatorIndex - 1;
            end1 = operatorIndex - 1;
            begin2 = operatorIndex + 1;
            end2 = operatorIndex + 1;
            char[] breakChars = {'/', '*', '-', '+', ' '};
            int[] breakCharPos = new int[5];
            while (expression.charAt(end1) == ' ') {
                end1--;
            }
            for (int i = 0; i < breakChars.length; i++) {
                breakCharPos[i] = expression.lastIndexOf(breakChars[i], end1);
            }
            begin1 = max(breakCharPos) + 1;
            while (expression.charAt(begin2) == ' ') {
                begin2++;
            }
            for (int i = 0; i < breakChars.length; i++) {
                breakCharPos[i] = expression.indexOf(breakChars[i], begin2);
                if (breakCharPos[i] == -1) {
                    breakCharPos[i] = expression.length();
                }
            }
            end2 = min(breakCharPos);
            String num1 = expression.substring(begin1, end1 + 1);
            String num2 = expression.substring(begin2, end2);
            double[] nums = {Double.parseDouble(num1), Double.parseDouble(num2)};
            System.out.println("getNums");
            System.out.println(nums[0] + ", " + nums[1]);
            return nums;
        }
    }
    Full Text of TestMath2.Java (args = "5*3 + 2^3 - 8 + 7 * 2"):
    Java Code:
    import myMods.Math2;
    // this is just a basic class to try out the simplify method quickly
    public class TestMath2 {
        public static void main(String[] args) {
            System.out.println(Math2.simplify(args[0]));
        }
    }

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: replaceAll(string a, string b) not working as expected

    the "expression" variable isn't being changed
    What are the values of original, result and expression just before the call to replaceAll()?

    Are you aware that replaceAll() interprets its first argument as a regular expression? ^ does not mean, in a regex, what it means in an arithmetic expression. If what you are trying to do is replace character sequences with what they evaluate to perhaps you could consider a mutable class like StringBuilder which provides a replace() method that straightforwardly replaces a sub sequence (specified by index) with some other sequence.

  3. #3
    Bronsonboy is offline Member
    Join Date
    Jun 2012
    Location
    Illinois
    Posts
    4
    Rep Power
    0

    Default Re: replaceAll(string a, string b) not working as expected

    The values are as follows:
    "2^3" (original)
    "8.0" (result)
    and
    "5*3 + 2^3 -8 + 7 * 2" (expression).

    Yes, I looked Regular Expressions up, but was confused by the available documentation (it was over my head; I've only been programming for a month or so).

    Finally, using StringBuilder (with replace() and toString()) works as I want. Thank you for the suggestion.

    EDIT: I have now (I think) fully debugged the program. Thanks again for the help. I wouldn't have found that on my own.
    Last edited by Bronsonboy; 07-15-2012 at 08:57 PM.

  4. #4
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,574
    Rep Power
    12

    Default Re: replaceAll(string a, string b) not working as expected

    You're welcome, I'm glad you've got it sorted out.

    Yes, regular expressions are as cryptic as the documentation suggests. There are ways of forcing replaceAll() to do what you want in this case but these involve changing the first argument so that ^ (and any other "special" characters) don't muck things up. Easier, I think, with the mutable classes like StringBuilder.

Similar Threads

  1. String replaceAll doesn't work!!!
    By danoc93 in forum New To Java
    Replies: 3
    Last Post: 06-25-2012, 12:29 PM
  2. Replies: 1
    Last Post: 10-08-2011, 06:41 AM
  3. Replies: 2
    Last Post: 07-21-2011, 04:46 AM
  4. Replies: 2
    Last Post: 04-25-2011, 05:13 PM
  5. Regular Expressions and String.replaceAll()
    By meta1203 in forum New To Java
    Replies: 1
    Last Post: 11-25-2010, 12:41 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •