化学式分子符号的扩展

时间:2015-07-10 19:59:02

标签: java chemistry

我环顾了一下解决方案,解析出一个含有分子成分的化学式,这些分子成分可能有自己的后缀,以便能够解析其完整原子分数的公式。

如何用Java做到这一点?

1 个答案:

答案 0 :(得分:0)

没有能够在短时间内找到一种方法(并且暂时没有做过有趣的算法)我决定使用堆栈实现,因为它实际上比数学运算堆栈复杂

向后浏览堆栈,您只需要了解一些事情,因为这基本上是解析数学语句的通用解决方案的修改实现。

1)您的整数后缀可以由多个字符组成 2)你的整数后缀可以是一个乘数(下一个字符是")")
3)你需要处理隐含的" 1" s

该实现将字符从一个堆栈弹出,并仅将字母和数字推送到"返回堆栈"。

String expandFormula(String s){
    Stack<Character> stack = new Stack();
    Stack<Character> hanoi = new Stack();
    char[] ca = s.toCharArray();
    Character c;
    List<Integer> multipliers = new ArrayList();
    String multiBuff;

    int val;
    boolean flag;

    for (int i = 0; i < ca.length; i++)
        stack.push(ca[i]);

    while(!stack.isEmpty()){
        c = stack.pop();
        if (Character.isLetter(c)){ 
            try{
                //previous parse was end of Symbol, implicit "1"
                flag = Character.isUpperCase(hanoi.peek());
            }
            catch(EmptyStackException ese){ //change exception
                flag = false;
            }
            //push implicit 1
            if (flag){
                stack.push(c);
                stack.push('1');
            }
            //continue as usual
            else
                hanoi.push(c);
        }
        //begin number parsing
    else if(Character.isDigit(c)){
            flag = false;
            multiBuff = c +"";
            //parse the integer out
            while(Character.isDigit(stack.peek())){
                c = stack.pop();
                multiBuff = c + multiBuff;
            }
            //if next char is ), then value is a suffix
            if (stack.peek() == ')'){
                flag = true;
                stack.pop();
                multipliers.add(Integer.parseInt(multiBuff));
                //pop successive )s
                while(stack.peek() == ')'){
                    stack.pop();
                    multipliers.add(1);
                }
            }
            if(Character.isLetter(stack.peek())){
                val = flag ? 0 : Integer.parseInt(multiBuff);
                //get full value of 
                for(Integer i : multipliers){
                    if (val == 0)
                        val = i;
                    else
                        val *= i;
                }
                //trim and push first decibit
                while(val > 0){
                        hanoi.push(Character.forDigit(val % 10, 10));
                        val /= 10;
                }
            }
        }
        //end of nest, remove most recent multiplier
        else if(c == '(')
            try{
                multipliers.remove(multipliers.size()-1);
            }
            catch(ArrayIndexOutOfBoundsException aioobe){

            }
    }
    multiBuff = "";
    while(!hanoi.isEmpty())
        multiBuff += hanoi.pop();

    return multibuff;        
}

此解决方案可以通过以下方式直接转换为输出字符串:

1)改变&#34; hanoi&#34;串起来 2)改变&#34; hanoi.push(c)&#34;到hanoi = c + hanoi
3)改变&#34; hanoi.peek()&#34; to&#34; hanoi.charAt(0)&#34;
4)根据需要更改例外(或使用一般例外) 5)只需返回hanoi而不是底部的multibuff东西。