【问题标题】:Why does my code about Bracket Fixing hangs?为什么我的关于 Bracket Fixing 的代码会挂起?
【发布时间】:2022-01-03 11:52:35
【问题描述】:

我的代码将带有右括号“)”的表达式组合成一个完整的带有右括号“(”的表达式组合。如果右括号和左括号仍然不相等,则使第一个表达式最后一个优先级,如果仍然不相等,则对第一个索引进行左括号。最多三个表达式(表达式=数字运算符数字)。

示例输入: 4 + 3 ) * 4 - 2 ) * 6 - 6 ) ) )

样本输出: ((4 + 3 ) * ((4 - 2 ) * (6 - 6 ) ) )

我的代码在只放置 1-2 个右括号时有效。如果超过两个,程序就会挂起。

源代码:

import java.util.Scanner;
import java.lang.String;

public class brackets {     //Declaration of Variables
    static String Str, Strr="";
    static Integer ope=0;
    static int temp=0,lent,pr=0,prl=0,prr=0;   //Temp = Opening Brackets placed, lent = string length, pr=Closing Brackets, prl = number of opening brackets made from last index, prr=TBA
    static  Scanner scan = new Scanner(System.in);

    public static void main(String[]args){
        
        System.out.println("Enter the combined experessions: ");  
        Str = scan.nextLine();        
        lent = Str.length();       //Setting the full expression to a string (Str)
    

        for(int i=0; i<lent;i++){        //Finding how many Closing Brackets There are
 
            if(Str.charAt(i)==')'){
                pr++;
            }   

        }
        Popping(lent);                 //Method
        System.out.print(Strr);          //Printing Final Ouput
            

        scan.close();
        


    }

    public static void Popping(int lent){ 
     
        for(int j =lent-1; j>-1;j--){        //I set j to lent because I want to search from rightmost to leftmost
            if(Str.charAt(j)==')')          //I need to find a closing bracket first before the program could start to input an opening bracket
                prr++;

            if(prr>0){
                if(Str.charAt(j)=='+'||Str.charAt(j)=='-'||Str.charAt(j)=='*'||Str.charAt(j)=='/'||(j<=lent-2&&Character.isDigit(Str.charAt(j+1))&&Str.charAt(j)==')')){   //Finding an operator or finding a closing bracket which has a digit next to it 
                    ope++;
                }
                if(ope==2){  //finding two operators mean that I can now put an opening bracket
                    Strr = '('+Strr;
                    temp++;
                    ope=0;
                }
            }

        Strr = Str.charAt(j)+Strr;  

        if(prr>0){                 
            if(j==0&&temp!=pr){    //If J==0 and Closing brackets still is not equal to Opening Brackets, I'll set opening bracket to the 0 index
                Strr = '('+Strr;
                temp++;
            }
        }

        }

        while(temp!=pr) {   // If still not equal, I'll set an opening bracket to the second opening bracket there is, making the last two expression a priority
            for(int j =lent-1; j>-1;j--){
                if(Str.charAt(j)=='(')
                    prl++;
                if(prl>1&&Str.charAt(j)=='('){
                    Strr= Strr.substring(0,j-1)+'('+Strr.substring(j,lent-1);
                    temp++;
                }
            }
        }
   
       
    }
}

【问题讨论】:

    标签: java string search java.util.scanner brackets


    【解决方案1】:

    我认为问题出在您的最终 while 循环上。

    问题是您正在运行Str(您的原始字符串),寻找左括号。但是,您的原始字符串4 + 3 ) * 4 - 2 ) * 6 - 6 ) ) ) 不包含任何左括号,因此Str.charAt(j)=='(' 永远不会truetemp 永远不会增加以匹配pr。因此条件temp!=pr总是true,所以while循环继续执行。

    您可能希望将此循环中出现的所有Str 更改为Strr,这是您插入左括号的字符串。

    然后您将遇到以下行的问题:

                        Strr= Strr.substring(0,j-1)+'('+Strr.substring(j,lent-1);
    

    如果j &gt; 0,此行将排除Strrj-1 位置处的字符。如果j == 0 这将导致StringIndexOutOfBoundsException 被抛出。 .substring 方法的第二个参数不是要包含在子字符串中的最后一个字符的索引,而是之后下一个字符的索引。 Strr 的子字符串从开头,直到但不包括 j 位置的字符,是 Strr.substring(0,j) 而不是 Strr.substring(0,j-1)

    另外,为简单起见,如果您希望子字符串运行到​​字符串的末尾,您可以省略第二个参数。在下面的行中,我对您对.substring 的第二次调用进行了修改:

                        Strr= Strr.substring(0,j)+'('+Strr.substring(j);
    

    对您的类进行这些更改后,我能够在您的示例输入 4 + 3 ) * 4 - 2 ) * 6 - 6 ) ) ) 上运行它并从中获取输出 ((4 + 3 ) *(( 4 - 2 ) *( 6 - 6 ) ) )


    但是,我随后在 1 + 5 ) / 4 + 3 ) * 4 - 2 ) * 6 - 6 ) ) ) 上运行了您的代码,但它再次挂起。

    这里的问题是,当您的代码到达while 循环的顶部时,它会插入四个左括号,而剩下两个仍待关闭。但是,运行for 循环会给str 添加三个左括号,使temp 最多为7,当pr 为6。7 不等于6,所以while 循环的主体运行再次插入更多的括号,以此类推,直到字符串变得太大而无法放入内存并且程序崩溃。

    最简单的解决方法是将条件temp&lt;pr 添加到该行

    if(prl>1&&Strr.charAt(j)=='('){
    

    给你

    if(prl>1&&Strr.charAt(j)=='('&&temp<pr){
    

    这样你就不会插入太多的左括号。


    最后,为了便于阅读,我强烈建议您为变量提供更具描述性的名称。例如,temp 对于计算到目前为止插入的左括号数的变量来说不是一个好名字:更好的名字是openParenCount 或者insertedOpenParensCount。同样,pr 会比closeParenCount 更好。 Str 可以重命名为 originalStringStrr 可以重命名为 modifiedString

    【讨论】:

      【解决方案2】:

      我不确定您的代码在 while 循环中到底在做什么,但是我可以确认的一件事是,当输入大于 3 个关闭 ")" 括号时,您的代码将进入 while 循环

      while(temp!=pr) {   // If still not equal, I'll set an opening bracket to the second opening bracket there is, making the last two expression a priority
              for(int j =lent-1; j>-1;j--){
                  if(Str.charAt(j)=='(')
                      prl++;
                  if(prl>1&&Str.charAt(j)=='('){
                      Strr= Strr.substring(0,j-1)+'('+Strr.substring(j,lent-1);
                      temp++;
                  }
              }
          }
      

      此时您的while 会检查temp!=pr 是否在调用此条件时始终为真,从而创建一个无限循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-31
        • 2017-05-13
        相关资源
        最近更新 更多