计算字母出现次数【存在括号计算】
此代码考虑到了本问题的大多可能情况,闲话少述,代码中的注释很丰富。
代码绝对可以解决你的问题!
不行你就评论,回复速度超快
作者 | 时间 |
---|---|
YaoChongChong | 2023年6月14日10:40 |
Description of this problem:
input:
AS2(D22F7Z)8(X3C1)8A9B1mindset:
first of all,analysis:A1,S2,D22* 8,F7* 8,Z1* 8,X3* 8,C1* 8,A9,B1
and then,merge this numbers by the same character.
last,print this in sort of sequence by character dictionary.
output:
A10B1C8D176F56S2X24Z8
import java.util.Locale;
import java.util.Scanner;
import java.util.Stack;
/**
* @Author: JarmanYao 【姚崇崇】
* @Date: 2023/6/13 19:14
*/
public class countForEveryCharacterUtils {
//主程序测试
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
countForEveryCharacter(input);
}
/**
* 统计字符串中各字母出现的次数
*
* 我考虑的情况如下:
* 1.输入存在大小写不一致
* 2.跟随在字符后面的数字,可能是""【比如XYZ】,也可能是多位数【占据多位,比如X123Y98】
* 3.考虑到括号存在乘法运算,我将括号临时独立运算,再将结果合并到最终结果数组中。
*
* @param str
*/
public static void countForEveryCharacter(String str) {
str = str.toUpperCase(Locale.ROOT);//如果输入存在小写,全部改写为大写
int[] count = new int[26];//最终结果
int[] countTem = new int[26];//暂存括号运算结果
for(int i=0;i<str.length();i++){
//考虑括号情况:
int k = i;
int kuoHaoFlag = 1;
boolean flag = false;
if(str.charAt(k)=='('){//这个左括号,是独立区域的最外侧括号的左半部分
Stack<Character> stack = new Stack<>();
do{
flag=false;
if (str.charAt(k)==')'){
Stack<Character> stackTem = new Stack<>();
int[] nu = get_numberAfterChar_and_nextIndex(k,str);//获取最里面的括号的右侧那个数nu[0],进行乘法运算(在临时的countTem数组进行)
while(stack.size()!=0 && stack.peek()!='(') {
stackTem.push(stack.peek());
countTem[stack.pop()-'A'] *= nu[0];//乘法运算
}
if (stack.peek()=='('){//这对括号,被干掉了,kuoHaoFlag记录括号数目,进行-1操作
stack.pop();
kuoHaoFlag--;
//如果这是最后一个左括号:
if (stack.size()==0) {
flag = true;
}
}
while(stackTem.size()!=0){//拿出来的还得再放回去,防止左括号还没有被匹配消除完:上面这些弹出来的内容还有再进行乘法操作的可能
stack.push(stackTem.pop());
}
k = nu[1];
i=k;//将i移动到下一个非数字字符的位置【nu[1]已经将‘(’除外】
continue;
}
if (str.charAt(k)=='('){//如果又发现了内部括号
stack.push(str.charAt(k));//左括号入栈
if (k!=str.indexOf('(')) kuoHaoFlag++;//括号对数+1
k++;
i=k;
continue;
}
stack.push(str.charAt(k));//往栈里面压字符
int[] nu = get_numberAfterChar_and_nextIndex(k,str);//获取被压进栈中那个字符后面对应的数目,以及下一步i应该调到哪里
countTem[str.charAt(k)-'A'] += nu[0];
k = nu[1];//已经包含了k++
i=k;
}while((flag||kuoHaoFlag>=1) && k<str.length());
//将括号运算结果合并到之前左侧的旧结果。
for (int j = 0; j < 26; j++) {
count[j]+=countTem[j];
}
countTem = new int[26];//对临时数组 刷新初始化覆盖旧缓存
i--;
continue;
}
//正常情况下,操作如下:
int[] nu = get_numberAfterChar_and_nextIndex(i,str);
count[str.charAt(i)-'A'] += nu[0];
i = nu[1]-1;
}
for (int i = 0; i < count.length; i++) {
if (count[i] != 0) {
System.out.print((char) (i + 'A'));
System.out.print(count[i]);
}
}
}
/**
* 获取:
* 1.str中位于i处的字符,他紧挨着右边的出现次数【存放在 结果数组的[0]】
* 2.i在接下来应该调整到的位置【存放在 结果数组的[1]】
* @param i
* @param str
* @return
*/
public static int[] get_numberAfterChar_and_nextIndex(int i, String str){
int j = i+1;
String num = "";
if (j>=str.length()){
num="1";
}else {
while (j<str.length() && str.charAt(j) >= '0' && str.charAt(j) <= '9') {
num += str.charAt(j);
j++;
}
if (num.equals("")){
num="1";
}
}
int[] result = {Integer.parseInt(num), j};
return result;
}
}
总结: 我自想解决算法写代码的过程,遇到了两次bug,当然,这属于代码自测环节,利用idea丰富的调试工具,快速地定位了问题所在,再迅速进行代码调整。最终也是搞定了这个代码。其实,原题中的描述,比我上面写的案例简单了很多,我考虑的更多了点。
要是在公司里,这我肯定先存着不交付它,哈哈哈,万一咱想的多,但是不符合下游的要求呢【交付的一定是仅仅能解决需求方的描述即可,如果存在想法,可以先沟通,再出力】。但是面试笔试就尽量展示自己的考虑全面吧。
兄弟看好你,点个赞吧。