2015-12-01 4 views
-1

Я пишу по методу, который должен анализировать полином, заданный пользователем (как String), и делать с ним разные вещи в будущем. На данный момент я пытался проверить код, который у меня есть до сих пор, но всякий раз, когда я запускаю программу, он замерзает и после нескольких часов работы перед компьютером я все еще не могу найти виновника.Программа зависает при попытке проанализировать строку

Я тестировал, можно ли проанализировать многочлен от одной переменной, а затем перепечатать, но это не сработает.

Я надеялся, что кто-нибудь может помочь мне в этом.

Вот код блок в основном, который выполняет метод, строка UserInput является многочлен (например, 4м 6м^2):

String userInput = inputArea.getText().trim(); 
Monomials monomials = new Monomials(); 
monomials.analyse(userInput); 

Вот классовые одночленов со своим методом анализа():

//Class Monomial 
class Monomials 
{   
    private int coeff = 0; 
    private char var; 
    private int addpow = 1; 
    private int pow; 
    private char powsign = '^'; 
    private char minus = '-'; 
    private boolean isnegative = false; 
    private String mono; 

    StringBuilder stringBuilder = new StringBuilder(); 

    public int getCoeff(int coeff) 
    { 
     return coeff; 
    } 

    public void setCoeff(int coeff) 
    { 
     this.coeff = coeff; 
    } 

    public void setVar(char var) 
    { 
     this.var = var; 
    } 

    public void setPow(int pow) 
    { 
     this.pow = pow; 
    } 

    public String getMono(String monomials) 
    { 
     return mono; 
    } 

    // Method to further analyse user's input. 
    public void analyse(String polynomial) 
    { 
     //Split the poynomial into monomials and store them in an array list. 
     polynomial = polynomial.replaceAll("-","+-"); 
     String polyParts[] = polynomial.split("\\+"); 
     ArrayList<String> monomials = new ArrayList<String>(Arrays.asList(polyParts)); 

     // Iterate the monomials. 
     for (int i = 0; i <= monomials.size(); i++) 
     { 
      String monomial = monomials.get(i); 

      // Analyse the monomial. 
      for (int x = 0; x <= monomial.length(); x++) 
      { 
       char c = monomial.charAt(x); 
       int countcoeff = 0; 
       int countvar = 0; 

       // check if negative. 
       if (c == minus) 
       { 
        isnegative = true; 
        x++; 
       } 
       // get the coefficient. 
       if (Character.isDigit(c)) 
       { 
        while (Character.isDigit(c)) 
        { 
         countcoeff++; 
         x++; 
        } 
        if (isnegative) 
        { 
         setCoeff(Integer.parseInt(monomial.substring(1, countcoeff))); 
        } else 
        { 
         setCoeff(Integer.parseInt(monomial.substring(0, countcoeff))); 
        } 
       } 
       // get the variable. 
       if (Character.isLetter(c)) 
       { 
        char var = c; 
        while (Character.isLetter(var)) 
        { 
         countvar++; 
         addpow++; 
         x++; 
        } 
       } 
       // get the power. 
       if (c == powsign) 
       { 
        countvar++; 
        x++;   
        while (Character.isDigit(c)) 
        { 
         x++; 
        } 
        if (isnegative) 
        { 
         setPow(Integer.parseInt(monomial.substring(countcoeff+countvar+2, x))); 
        } else 
        { 
         setPow(Integer.parseInt(monomial.substring(countcoeff+countvar+1, x))); 
        } 
        pow += addpow; 
       } 
      } 

      if (isnegative) 
      { 
       stringBuilder.append(String.valueOf(minus)); 
      } 
      stringBuilder.append(String.valueOf(coeff) + String.valueOf(var) + String.valueOf(powsign) + String.valueOf(pow)); 
      mono = stringBuilder.toString(); 
      monomials.set(i, mono); 
     } 

     for (int i = 0; i < monomials.size(); i++) 
     { 
      System.out.println(String.valueOf(monomials.get(i))); 
     } 
    } // End of method analyse(). 

} // End of class Monomial 
+3

вы можете установить System.out.println на разных этапах, чтобы увидеть, что происходит –

+0

Добавляйте ко всем «использовать отладчик»/«use' System.out», позвольте мне также добавить «break this method up!». Всюду, где у вас есть комментарий, вы говорите приятно и громко, что метод слишком велик. Вы должны разделить их и посмотреть, можете ли вы самостоятельно протестировать новый, небольшой метод через структуру тестирования (например, Junit или NGTest). –

+0

Возможный дубликат [Что такое отладчик и как он может помочь мне диагностировать проблемы] (http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Raedwald

ответ

2

У вас есть несколько петель, которые никогда не выход:

while (Character.isDigit(c)) 
{ 
    countcoeff++; 
    x++; 
} 

Как узнать такие вещи, как это? Если вы используете Eclipse, вы можете запустить свой код в режиме отладки, переключиться на перспективу отладки и щелкнуть по желтому символу Suspend-Symbol. Это приведет к приостановке вашей программы, в Debug-View вы увидите, в какой строке Thread «висит», если вы нажмете на нее, она откроет исходный код.

Если вы не используете IDE с этой функцией, вы можете использовать JDK-Tools: Используйте jps, чтобы узнать ID вашей программы:

C:\jdk\jdk8u45x64\jdk1.8.0_45\bin>jps 
7216 
5688 Jps 
6248 Monomials 

Затем использовать jstack для печати трассировки стека всех запущенных потоков:

C:\jdk\jdk8u45x64\jdk1.8.0_45\bin>jstack 6248 
[other threads omitted] 

"main" #1 prio=5 os_prio=0 tid=0x000000000203e800 nid=0x1b2c runnable [0x000000000201e000] 
    java.lang.Thread.State: RUNNABLE 
     at Monomials.analyse(Monomials.java:77) 
     at Monomials.main(Monomials.java:10) 
1

Один из ваших циклов работает бесконечно. Вы должны заменить его условием if.

while (Character.isDigit(c)) 
       { 
        countcoeff++; 
        x++; 
       } 

заменить его

if (Character.isDigit(c)) 
       { 
        countcoeff++; 
        x++; 
       } 

Или вы могли бы использовать заявление перерыв здесь.

0

Как другие заявили уже

while (Character.isDigit(c)) 

- ваша проблема. Но у вас есть это два раза не один раз, поэтому обе проблемы. Второй вопрос не является реальной проблемой, потому что Character.isDigit и if (c == powsign) не могут быть одновременно истинными, поэтому цикл 2-го цикла inifit никогда не будет выполнен, что приведет меня к следующему пункту: ошибки.
В вашем коде есть огромное количество из них: -D
Оба для петель бегут далеко (<= .size() & <= .length()), заменить < = с <.
Кроме того, x ++, размещенный в вашем коде, неверен. x автоматически увеличивается, и если вы хотите выйти из цикла раньше, используйте break; или используйте continue;, если вы хотите перейти на следующую итерацию раньше.

+0

Большое вам спасибо, хотя hinneLinks дал лучший ответ на мой вопрос, вы намекнул на решение всех других проблем, возникших после избавления от бесконечного цикла. –

Смежные вопросы