-1

I am writing on a method which should analyse a polynomial given by the user (as String) and do different stuff with it in the future. At the moment, I was trying to test the code I have so far but whenever I execute the program, it freezes and after sitting for hours in front of the computer I still can't find the culprit in it.

I was testing if a polynomial of one variable could be analysed and then re-printed, but it doesn't work.

I hoped anyone could help me out on this.

Here's the code block in the main which executes the method, the string userInput is a polynomial (e.g 4x-6x^2):

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

Here's the class monomials with its method analyse():

//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
    you could put some System.out.println at different steps to see what happens – guillaume girod-vitouchkina Dec 01 '15 at 12:45
  • Do add on to all the "use debugger"/"use `System.out`" let me also add "break that method up!". Everywhere you have a comment you are stating nice and loud that the method is too large. You should split 'em out and see if you can test the new, small method independently via a testing framework (like Junit or NGTest) – Michael Lloyd Lee mlk Dec 01 '15 at 12:58
  • Possible duplicate of [What is a debugger and how can it help me diagnose problems](http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Raedwald Jan 29 '16 at 03:42

3 Answers3

2

You have a couple of loops which will never exit:

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

How to find out Stuff like that? If you use Eclipse, you can run your Code in Debug Mode, switch to the debug-perspective and click on the yellow Suspend-Symbol. That will suspend your Program, in the Debug-View you can see in which line the Thread is "hanging", if you click on it it will open the source-code.

If you don't use an IDE with that function, you can use the JDK-Tools: Use jps to find out the ID of your program:

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

Then use jstack to print a stack trace of all running threads:

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)
hinneLinks
  • 3,673
  • 26
  • 40
1

one of your loop is running infinitely. You should replace it with if condition.

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

replace it with

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

Or you could use break statement here.

Arslan Ashraf
  • 867
  • 7
  • 12
0

As the others stated already

while (Character.isDigit(c))

is your problem. But you have that two times not one time, so both are a problem. The 2nd isn't a real problem, because Character.isDigit and if (c == powsign) can´t be both true at the same time, so the 2nd inifit loop never gets executed, which brings me to the next point: bugs.
In your code there are a tremendous amount of them :-D
Both for loops are running to far (<= .size() & <= .length()), replace <= with <.
Also, the x++ placed around in your code are wrong. x gets incremented automaticially and if you want to exit the loop early, use break; or use continue; if you want to jump to the next iteration early.

BadK
  • 307
  • 3
  • 12
  • Thank you a lot, although hinneLinks gave the best answer to my question, you hinted out the solutions to all the other problems which arose after getting rid of the infinite loop. – weary soul Dec 01 '15 at 13:31