[算法-Java] 输入任意一种物质,要求输出其每种元素的数量。

题目全文

输入任意一种物质,要求输出其每种元素的数量。
例如:
输入 CaCO3,其组成分别为 Ca:1,C:1,O:3,输出 Ca1C1O3
输入 Fe2(SO4)3,其组成分别为 Fe:2,S:3,O:12,输出 Fe2S3O12

题目分析

思路就是利用栈.
首先把给定的字符串(例如CaCO3)转成字符数组,然后把字符数组压入栈中,然后逐渐弹出这个栈,来解决问题

至于算法的细节不再追究,每个人写的细节都会有偏差,但是大体思路不变

代码参考-Java版本


/**
 * 输入任意一种物质,要求输出其每种元素的数量。
 * 比如
 * 输入 CaCO3,其组成分别为 Ca:1,C:1,O:3,输出 Ca1C1O3
 * 输入 Fe2(SO4)3,其组成分别为 Fe:2,S:3,O:12,输出 Fe2S3O12
 * (注意:元素名称首字母大写,剩余字母都小写;括号括起来表示括号中的结构作
 * 为整体出现多少次)
 * @作者 Forest Hoo
 * @日期 2023-02-15 22:41
 */
public class ElementMy {
    public static void main(String[] args) {
        String str = "RCa(Fe2(SO4)3)2";
//        String str = "CaCO3";
        String result = getResult(str);
        System.out.println("result="+result);
    }

    private static String getResult(String str) {
        //准备
        Stack<Character> initStack = new Stack<>();     //初始的栈,第一次用来顺序入栈
        char[] chars = str.toCharArray();
        StringBuilder result = new StringBuilder();
        int factor = 1; //倍率
        Stack<Integer> integerStack = new Stack<>();    //辅助栈,里面存数字
        Stack<Character> bracketStack = new Stack<>();  //辅助栈,里面存大括号,小括号
        Stack<Integer> factorStack = new Stack<>();


        //处理
        for (int i = 0; i < chars.length; i++) {
            initStack.push(chars[i]);
        }

        while (!initStack.isEmpty()){   //就是这个初始的栈还没处理完,就继续
            Character popChar = initStack.pop();

            if (Character.isDigit(popChar)){    //字符是数字就返回true,不是数字就返回false
                Character peekChar = initStack.peek();  //是数字立马再取一个字符,但是不从原本的stack里面删除
                if (peekChar==')'){ //说明这个数字是倍率了
                   factor = factor * Integer.parseInt(String.valueOf(popChar));    //改变当前倍率
                    bracketStack.push(initStack.pop());     //如果当前字符是')',可以不要了
                    factorStack.push(Integer.parseInt(String.valueOf(popChar)));     //需要一个倍率栈
                }else {  // 再次取出的时候,不再是特殊的)了
                    int number = Integer.parseInt(String.valueOf(popChar)); //弹出的这个number,是不是最终结果呢?不是
                    integerStack.push(number);  //辅助栈,用来判断字母还需要乘以倍率吗
                    if (!bracketStack.isEmpty()){   //受到括号的约束,乘以倍率
                        number = number*factor;
                    }
                            //这个number要乘以最终的倍率
                    result.insert(0,number);
                }

                continue;
            }

            /**
             * 弹出的字母是小写字母
             */
            if (Character.isLowerCase(popChar)){
                char firstResultChar = result.charAt(0);
                if (Character.isUpperCase(firstResultChar)){//第一个又是大写字母
                    result.insert(0,factor);
                    result.insert(0,popChar);
                }else {
                    result.insert(0,popChar);
                }
                continue;
            }

            /**
             * 弹出的是大写字母的情况
             */
            if (Character.isUpperCase(popChar)){
                char firstResultChar = result.toString().charAt(0);
                if (Character.isLowerCase(firstResultChar)){
                    //result结果第一个字母是小写字母,直接头插就行了
                    result.insert(0,popChar);

                }
                else if (Character.isUpperCase(firstResultChar)){   //是大写字母
                    result.insert(0,factor);
                    result.insert(0,popChar);
                }
                else {//不是字母
                    if (integerStack.isEmpty()){
                        result.insert(0,factor);
                    }else {integerStack.pop();}

                    result.insert(0,popChar);
                }
                continue;
            }



            if (popChar=='('){      //那么需要弹出最顶层的一个左括号
                bracketStack.pop();
                Integer popFactor = factorStack.pop();
                factor = factor/popFactor;
                continue;
            }


        }
        //返回
        return result.toString();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值