算法求原子数量

给定一个化学式formula(作为字符串),返回每种原子的数量。

原子总是以一个大写字母开始,接着跟随0个或任意个小写字母,表示原子的名字。

如果数量大于 1,原子后会跟着数字表示原子的数量。如果数量等于 1 则不会跟数字。例如,H2O 和 H2O2 是可行的,但 H1O2 这个表达是不可行的。

两个化学式连在一起是新的化学式。例如 H2O2He3Mg4 也是化学式。

一个括号中的化学式和数字(可选择性添加)也是化学式。例如 (H2O2) 和 (H2O2)3 是化学式。

给定一个化学式 formula ,返回所有原子的数量。格式为:第一个(按字典序)原子的名字,跟着它的数量(如果数量大于 1),然后是第二个原子的名字(按字典序),跟着它的数量(如果数量大于 1),以此类推。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-atoms

输入:formula = “H2O”
输出:“H2O”
解释:
原子的数量是 {‘H’: 2, ‘O’: 1}。

import java.util.*;

public class Solution {
    class AtomNums{
        StringBuffer name;
        Integer nums;

        public StringBuffer getName() {
            return name;
        }

        public void setName(StringBuffer name) {
            this.name = name;
        }

        public Integer getNums() {
            return nums;
        }

        public void setNums(Integer nums) {
            this.nums = nums;
        }

        @Override
        public String toString() {
            return "AtomNums{" +
                    "name=" + name +
                    ", nums=" + nums +
                    '}';
        }
    }

    public String countOfAtoms(String str){
        LinkedList<AtomNums> a=new LinkedList<>();//符号栈
        LinkedList<Integer> b=new LinkedList<>();//数字栈
        for(int i=str.length()-1;i>=0;i--){

            if (str.charAt(i)>='0'&&str.charAt(i)<='9'){       //将数字压入栈中去
                int j=i;
                int flag=0;
                while (str.charAt(j)>='0'&&str.charAt(j)<='9'){
                    switch (flag){
                        case 0:
                                b.addLast((int)str.charAt(j)-48);
                                break;
                        case 1:
                                int temp=b.getLast();
                                b.removeLast();
                                b.addLast(((int)str.charAt(j)-48)*10+temp);
                                break;
                        case 2:
                            int temp1=b.getLast();
                            b.removeLast();
                            b.addLast(((int)str.charAt(j)-48)*100+temp1);
                            break;
                        case 3:
                            int temp2=b.getLast();
                            b.removeLast();
                            b.addLast(((int)str.charAt(j)-48)*1000+temp2);
                            break;

                    }
                    flag++;
                    j--;
                }
                i=j+1;
            }
            else {                       //如果为符号时
                if (str.charAt(i)==')')   //符号栈为空时 或者为‘)’时  直接压入符号栈
                {
                    AtomNums atomNums=new AtomNums();
                    StringBuffer stringBuffer=new StringBuffer(")");
                    atomNums.setName(stringBuffer);
                    a.addLast(atomNums);
                    if(!(str.charAt(i-1)>='0'&&str.charAt(i-1)<='9')){
                        b.addLast(1);
                    }
                }
                else {                   //如果符号栈不是空时
                    if (str.charAt(i)=='('){    //如果是“(”时就需要出栈
                        if(b.size()>0){                                 //防止(H)情况出现
                            LinkedList<AtomNums> tempAtom=new LinkedList<>();
                            Integer num1=b.getLast();
                            while (!a.getLast().getName().toString().equals(")")){
                                AtomNums atomNums=a.getLast();
                                a.removeLast();
                                atomNums.setNums(atomNums.getNums()*num1);
                                tempAtom.addLast(atomNums);
                            }
                            b.removeLast();
                            a.removeLast();//删除“)”
                            a.addAll(tempAtom);
                        }
                        else {
                            LinkedList<AtomNums> tempAtom=new LinkedList<>();
                            Integer num1=1;
                            while (!a.getLast().getName().toString().equals(")")){
                                AtomNums atomNums=a.getLast();
                                a.removeLast();
                                atomNums.setNums(atomNums.getNums()*num1);
                                tempAtom.addLast(atomNums);
                            }

                            a.removeLast();//删除“)”
                            a.addAll(tempAtom);
                        }


                        if((i-1>0)&&!(str.charAt(i-1)>='0'&&str.charAt(i-1)<='9')&&(str.charAt(i-1)!='(')){  //判断“(”前是否是字母
                            b.addLast(1);
                        }
                    }
                    else {
                        StringBuffer atomNam=new StringBuffer();
                        //如果为元素名称时
                       for (int j=i;j>=0;j--){

                           if(str.charAt(j)>='A'&&str.charAt(j)<='Z'){
                               i=j;
                               atomNam.append(String.valueOf(str.charAt(j)));
                               break;
                           }
                           else {
                               atomNam.append(String.valueOf(str.charAt(j)));
                           }
                       }
                        atomNam.reverse();  //的到元素的完整名称 并加入符号栈中
                        AtomNums atomNums=new AtomNums();
                        atomNums.setName(atomNam);
                        atomNums.setNums(1);
                        //直接求原子数量
                        if (b.size()==0){
                            b.addLast(1);
                        }
                        Integer num1=b.getLast();
                        b.removeLast();

                        atomNums.setNums(num1*atomNums.getNums());
                        a.addLast(atomNums);
                        //然后判断上一个字符是否为字母  是则 并向数字栈中压入1
                        if (i-1>=0){
                            if(str.charAt(i-1)>='A'&&str.charAt(i-1)<='z'&&str.charAt(i-1)!='('){
                                b.addLast(1);
                            }
                        }
                    }

                }
            }
        }
//        System.out.println(a);
        Map<String,Integer> map =new TreeMap<>();
        while(a.size()>0){
            if (map.get(a.getLast().getName().toString()) == null) {
                map.put(a.getLast().getName().toString(), a.getLast().getNums());
            } else {
                map.put(a.getLast().getName().toString(), map.get(a.getLast().getName().toString()) + a.getLast().getNums());
            }
            a.removeLast();

        }
        Set keySet=map.keySet();

        Iterator it = keySet.iterator();


        String return_str="";

        while (it.hasNext()){
            Object key=it.next();
            Object value=map.get(key);
                if (map.get(key)>1)
                    return_str+=key.toString()+value.toString();
                else
                    return_str+=key.toString();
        }

        return return_str;
    }


}

代码看起来比较多,但是逻辑上并不复杂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值