【递归算法】输入任意一种物质的化学分子式,要求输出其每种元素的数量.

在百度上看到一个问题,题目是:

1. 编程题

输入任意一种物质,要求输出其每种元素的数量.
比如
输入CaC03 ,其组成分别为Ca : 1, C : 1,0 : 3 ,输出CalC103
输入 Fe2(SO4)3 ,其组成分别为 Fe : 2 , S : 3,0 : 12 ,输出 Fe2S3O12
(注意:元素名称首字母大写,剩余字母都小写;括号括起来表示括号中的结构作为整体出现多少次)

参考链接:
输入任意一种物质,要求输出其每种元素的数量

2. 思路其实还是分治, 逐层迭代渐降

package org.example;

import java.util.*;

public class BaiduTest {
    static Map<String, Integer> map = new HashMap<>();

    public static void main(String[] args) {
        String demo = "C3((CO)2)4";
        System.out.println(demo);
        splitString(demo, 1);
        System.out.println(map);
    }

    private static void splitString(String demo, int rdx) {
        List<String> list = new ArrayList<>();
        int idx = 0;
        for (int i = 0; i < demo.length(); i++) {
            char c = demo.charAt(i);
            if (Character.isUpperCase(c) && i != idx || c == '(') {
                String keyVal = demo.substring(idx, i);
                list.add(keyVal);
                idx = i;
                if (c == '(') {
                    i = demo.lastIndexOf(')');
                }
            }
        }
        if (idx < demo.length()) {
            list.add(demo.substring(idx));
        }
        for (String val : list) {
            if (val.contains("(")) {
                int composeVal = getComposeVal(val);
                splitString(val.substring(1, val.lastIndexOf(')')), composeVal * rdx);
            } else {
                putMap(val, rdx);
            }
        }
    }

    // (S3(CA)O4)300
    private static int getComposeVal(String val) {
        int rdx = 1;
        int idx = val.lastIndexOf(')');
        if (++idx < val.length())
            rdx = Integer.valueOf(val.substring(idx));
        return rdx;
    }

    private static void putMap(String keyVal, int rdx) {
        String key;
        int val = 1;
        int k = 0;
        for (int i = 0; i < keyVal.length(); i++) {
            if (Character.isDigit(keyVal.charAt(i))) {
                k = i;
                break;
            }
        }
        if (k != 0) {
            key = keyVal.substring(0, k);
            val = Integer.valueOf(keyVal.substring(k));
        } else {
            key = keyVal;
        }
        if (!key.isEmpty()) {
            Integer result = map.get(key);
            if (result == null)
                result = 0;
            map.put(key, val * rdx + result);
        }
    }
}

3. 算法解析:

3.1 存取元素得出现次数

用 map<string,integer> 保存, 实现很方便

3.2 分隔字符串

用大写字符以及 ‘(’ 表示一个完整字符串的结束,
分隔完的字符串的形式:
为"Key" ,“KeyVal”,“(KeyVal)Val”,“((KeyVal)Val)Val” 等

3.3

没有Val 表示有1次
如果有() 嵌套, val 记得相乘

4. 运行结果:

缺少语法分析,判断是否合法,比如 括号是否对称之类

C3((CO)2)4
{C=11, O=8}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值