日期:2014-05-20  浏览次数:20702 次

求高手帮忙写个算法
首先祝大家过年好。
我的问题是这样:
有一种字符串表示的查询条件,如:name=wang,这是单一条件的,如果有多个条件以"与"或者"或"的关系出现,则表示方法是这样:&(name=wang)(age=20),或者:|(name=wang)(name=li)(name=zhao),大家可以看出,就是将"与"或者"或"的符号写在最前面,而将每个条件用圆括号括起来挨个写在后面。当然,大家知道,单纯的"与"、"或"关系有时候不能解决复杂的逻辑,所以"&"、"|"有可能嵌套出现多次,如这种写法:&(|(name=wang)(name=li))(age=20),这就表示"name=wang或者name=li、并且age=20".

然而QA总是能找到问题,我们是用圆括号表示一个条件的,但是如果条件信息里本身就有"("或")"怎么办,如&(name=(wang)(age=20),对于这样的信息,第二个"("应该是属于有用的条件信息,就是name=(wang,试了一下,对于这样的信息,我们以前的代码确实出现处理错误,所以现在需要的是将应该属于正常查询条件信息的"("或")"进行一个转义,转义方法是这样:如果这个需要转的字符是"(",则需要转为:Integer.toHexString('('),")"也以同样的方法。这样我们的代码就不会将其当做边界符"("或")"处理。

现在的问题就是怎样判断一个"("或")"是有用的条件信息还是表示边界的符号。求达人们给段代码,最好写成方法,传入原始输入的条件字符串,返回转换后的字符串。

如&(name=wang))(age=20)应该会变成&(name=wang\29)(age=20)输出,如果最外层有多余的成对的"()"则可以直接去掉,如只有一个条件的还加了括号((name=wang)),这样的多层括号其实已经是多余的,只要是成对的,就不用处理,可以直接返回,也可以返回(name=wang)或name=wang,但是有落单的"("或")"就必须转义。

------解决方案--------------------
(name=(wang)怎么说?
------解决方案--------------------
(name=(wang))怎么说?
------解决方案--------------------
不知道这样可符合?
for example
Java code

import java.util.*;
public class csdn {
    public static void main(String[] args) throws Throwable {
        String testData[] = {"&((name=wang))(age=20)",
                             "&((name=wang)(age=20)",
                             "&(name=wang))(age=20)",
                             "&(name=wang)))((age=20)",
                             "&(((name=wang))((age=20))))"};

        for (String str : testData) { //测试数据
            convert(str);
        }
    }

    public static String convert(String str) {
        Stack<String> st = new Stack<String>();
        List<String> ls = new ArrayList<String>();
        StringBuilder sb = new StringBuilder();
        boolean match = false;

        for (int i=0; i<str.length(); i++) { //先转换多余的")"
            String s = str.substring(i, i+1);
            if (s.equals(")")) {
                sb.delete(0, sb.length());
                match = false;
                while (st.size() > 0) {
                    String ss = st.pop();
                    if (ss.equals("(")) {
                        if (sb.length() == 0 ||
                            (sb.charAt(0) == '(' && 
                             sb.charAt(sb.length()-1) == ')')) {
                            st.push(sb.toString());
                        } else {
                            sb.insert(0, ss);
                            sb.append(s);
                            st.push(sb.toString());
                        }
                        match = true;
                        break;
                    } else {
                       sb.insert(0, ss);
                    }
                }
                if (!match) {
                    if (sb.charAt(sb.length()-1) == ')') {
                        sb.deleteCharAt(sb.length()-1);
                        sb.append(String.format("\\%x", (int)(')')));
                        sb.append(s);
                    } else {
                        sb.append(String.format("\\%x", (int)(')')));
                    }
                    st.push(sb.toString());
                }
            } else {
                st.push(s);
            }
        }

        while (st.size() > 0) { //再转换多余的"("
            String s = st.pop();
            if (s.equals("(")) {
                if (ls.size() > 0) {
                    String ss = ls.remove(0);
                    if (ss.startsWith("(") && ss.endsWith(")")) {
                        ls.add(0, String.format("%s\\%x%s",
                                  s, (int)('('), ss.substring(1)));
                    } else {
                        ls.add(0, String.format("\\%x", (int)('(')));
                    }
                } else {
                    ls.add(String.format("\\%x", (int)('(')));
                }
            } else {
                ls.add(0, s);
            }
        }

        sb.delete(0, sb.length());
        for (String s : ls) { //获得最后结果
            sb.append(s);
        }
        System.out.println(sb);

        return sb.toString();
    }
}