题目全文
输入任意一种物质,要求输出其每种元素的数量。
例如:
输入 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();
}
}