首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

求好手帮忙写个算法

2012-08-10 
求高手帮忙写个算法首先祝大家过年好。我的问题是这样:有一种字符串表示的查询条件,如:namewang,这是单一

求高手帮忙写个算法
首先祝大家过年好。
我的问题是这样:
有一种字符串表示的查询条件,如: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();    }} 


[解决办法]
发现上面有失误,修改了一下

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)", //here                             "&(name=wang))(age=20)",                             "&(name=wang)))((age=20)",                             "&(((name=wang))((age=20))))",                             "&(|(name=wang)(name=li))(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);            }        }        sb.delete(0, sb.length());        while (st.size() > 0) {            String s = st.pop();            if (s.equals("(")) {                 if (sb.length() > 0) {                    int idx = sb.indexOf("(");                    if (idx >= 0) {                        sb.replace(idx, idx+1, String.format("\\%x", (int)('(')));                        sb.insert(0, s);                    } else {                        sb.insert(0, String.format("\\%x", (int)('(')));                    }                } else {                    sb.append(String.format("\\%x", (int)('(')));                }                ls.add(0, sb.toString());                sb.delete(0, sb.length());            } else {                sb.insert(0, s);            }        }        if (sb.length() > 0) {            ls.add(0, sb.toString());        }        sb.delete(0, sb.length());        for (String s : ls) {            sb.append(s);        }        System.out.println(sb);        return sb.toString();    }}
[解决办法]
类似于中值遍历,搞个调用栈呗
[解决办法]
&(|(name=wang)(name=li))(age=20)
大哥你是不是少些了个括号啊按照你说的逻辑判断应该是这样的把
&(|(name=wang)(name=li)))(age=20)
[解决办法]
协议或者文件格式或者dsl的设计一定要考虑到所有特殊情况,特别是转义,(有经验的话考虑这些花不了你几分钟),一个合格的程序员在开始设计前就应该考虑清楚这些问题,而不是在实现出来之后修修补补,那样太晚了。



自己缺少经验就多向成熟产品学习借鉴。SQL用过吧?SQL是怎么解决这个问题的?字符串用引号包围起来就可以了啊。而且还支持field1=field2这种写法。比自己造个奇丑无比的新语法强多了。

试着把自己的语法形式化出来,然后语法里有没有漏洞就一目了然。
[解决办法]

探讨

&amp;(|(name=wang)(name=li))(age=20)
大哥你是不是少些了个括号啊按照你说的逻辑判断应该是这样的把
&amp;(|(name=wang)(name=li)))(age=20)

热点排行