Программа зависает при попытке анализа строки
Я пишу о методе, который должен анализировать полином, заданный пользователем (как String), и делать с ним другие вещи в будущем. В данный момент я пытался протестировать код, который у меня есть, но когда я запускаю программу, она зависает, и после нескольких часов сидения за компьютером я все еще не могу найти виновника в этом.
Я проверял, можно ли проанализировать и затем перепечатать многочлен одной переменной, но он не работает.
Я надеялся, что кто-нибудь может помочь мне в этом.
Вот кодовый блок в main, который выполняет метод, строка userInput является полиномом (например, 4x-6x^2):
String userInput = inputArea.getText().trim();
Monomials monomials = new Monomials();
monomials.analyse(userInput);
Вот мономы класса с его методом analysis ():
//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 ответа
У вас есть пара циклов, которые никогда не выйдут:
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
Как это выяснить? Если вы используете Eclipse, вы можете запустить свой код в режиме отладки, переключиться на перспективу отладки и нажать на желтый символ Suspend-Symbol. Это приостановит вашу Программу, в Debug-View вы можете увидеть, в какой строке Поток "висит", если вы щелкните по нему, откроется исходный код.
Если вы не используете IDE с этой функцией, вы можете использовать JDK-Tools: Use jps
чтобы узнать идентификатор вашей программы:
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)
Один из ваших циклов работает бесконечно. Вы должны заменить его, если условие.
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
заменить его на
if (Character.isDigit(c))
{
countcoeff++;
x++;
}
Или вы можете использовать оператор break здесь.
Как уже говорили другие
while (Character.isDigit(c))
это твоя проблема. Но у вас есть это два раза, а не один раз, так что оба проблемы. Второе не настоящая проблема, потому что Character.isDigit
а также if (c == powsign)
оба не могут быть истинными одновременно, поэтому 2-й цикл инициализации никогда не выполняется, что подводит меня к следующему пункту: ошибкам.
В вашем коде их огромное количество:-D
Обе петли бегут далеко (<= .size() & <= .length()
), заменить <= на <.
Кроме того, x++, размещенный в вашем коде, неверен. x автоматически увеличивается, и если вы хотите выйти из цикла раньше, используйте break;
или использовать continue;
если вы хотите перейти к следующей итерации раньше.