Question

I'm dealing with logical expressions in strings. So far I have worked on the following method.

public static String modify(String expression)
    {
        String temp = expression;
        String validated = "";

        for(int idx=0; idx<temp.length(); idx++)
        {
            if(idx!=temp.length()-1)
            {
                if((Character.isAlphabetic(temp.charAt(idx))) && (Character.isAlphabetic(temp.charAt(idx+1))))
                {
                    validated+=temp.substring(idx,idx+1);
                    validated+="*";
                }
                else
                    validated+=temp.substring(idx,idx+1);
            }
            else
                validated+=temp.substring(idx);
        }

        return validated;
    }

The following are examples of supposed input/output input: AB+BC+ABC / output: (A*B)+(B*C)+(A*B*C) input: (A+B)+ABC / output: (A+B)+(A*B*C) input: (A+B)*(B+C)*(AB) / output: (A+B)*(B+C)*(A*B)

Was it helpful?

Solution

One way you can do it is simply keeping track of brackets with a boolean semaphore

public static String modify(String expression)
    {
        String temp = expression;
        StringBuilder validated = new StringBuilder();
        boolean inBrackets=false;

        for(int idx=0; idx<temp.length()-1; idx++)
        {
            if((Character.isLetter(temp.charAt(idx))) && (Character.isLetter(temp.charAt(idx+1))))
            {
                if(!inBrackets){
                    inBrackets = true;
                    validated.append("(");
                }
                validated.append(temp.substring(idx,idx+1));
                validated.append("*");
            }
            else{
                validated.append(temp.substring(idx,idx+1));
                if(inBrackets){
                    validated.append(")");
                    inBrackets=false;
                }
            }
        }
        validated.append(temp.substring(temp.length()-1));
        if(inBrackets){
            validated.append(")");
            inBrackets=false;
        }
        return validated.toString();
    }

Also never use string concatenation instead use StringBuilder or its predecessor StringBuffer in case you are seeking thread safe solution.

OTHER TIPS

Here is what I would do, using StringBuilder and a split:

public static String modify(String expression)
{        
    StringBuilder finalString = new StringBuilder();

    String[] subExpressions = expression.split("\\+");
    List<String> formattedSubExpressions = new ArrayList<String>();

    for (String subExpression : subExpressions) {
        if (subExpression.length() > 1) {
            StringBuilder formattedSubExpression = new StringBuilder();
            formattedSubExpression.append("(");
            for (int i=0; i<subExpression.length(); i++) {
                formattedSubExpression.append(subExpression.charAt(i));
                if (i != subExpression.length() -1 ) {
                    formattedSubExpression.append("*");
                }
            }
            formattedSubExpression.append(")");
            formattedSubExpressions.add(formattedSubExpression.toString());
        } else {
            formattedSubExpressions.add(subExpression);
        }
    }

    for (String subExpression : formattedSubExpressions) {
        finalString.append(subExpression);
        finalString.append("+");
    }

    if (finalString.charAt(finalString.length() - 1) == '+') {
        finalString.deleteCharAt(finalString.length() - 1);
    }

    return finalString.toString();
}

It gives the following sample input/output:

AB+CD: (A*B)+(C*D)
AB+CD+EF: (A*B)+(C*D)+(E*F)
AB+CD+EFGH: (A*B)+(C*D)+(E*F*G*H)

I based this answer on the idea that what you want to do is group repeating alpha characters between parentheses and put an asterisks between them regardless of the operation (add, subtract, divide, etc) being performed between the groups.

private static final Pattern p = Pattern.compile("[a-zA-Z]{2,}");

public String parse(String s){
    if(s == null || "".equals(s)) {
        return s;
    }
    char[] chars = s.toCharArray();
    StringBuilder sb = new StringBuilder(100);
    Matcher m = p.matcher(s);
    int i = 0;
    while(i<chars.length && m.find()){
        int startIdx = m.start();
        int endIdx = m.end();
        // Need to get the leading part of the string before this matching region
        while(i < startIdx){
            sb.append(chars[i]);
            i++;
        }
        sb.append('('); // Start getting the match region
        while(i < endIdx){
            sb.append(chars[i]);
            if(i < endIdx - 1){
                sb.append('*');
            }
            i++;
        }

        sb.append(')'); // end the match region
    }
    // If there is a region beyond the last match, append it
    if(i < chars.length -1){
        for(; i < chars.length; i++){
            sb.append(chars[i]);
        }
    }
    return sb.toString();

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top