This question already has answers here:
What does a "Cannot find symbol" or "Cannot resolve symbol" error mean?
(18 answers)
Closed 5 years ago.
Need a little help figuring out why the last part of my code gives an error. Can anybody tell me what's wrong? I'm working with NetBeans for an intro level programming class and cant figure out the last bit of why this is wrong.
I'm getting the following error:
Cannot find symbol symbol: variable rat04 location: class Rational
package rational;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Rational {
// the numer and denom fields represent a fraction
// CLASS INVARIANTS:
// CI1: denom is not 0,
// CI2: denom is positive,
// CI3: numer and denom are in lowest terms.
private final int numer;
private final int denom;
//toString and toDouble
public String toString() {
return numer + "/" + denom;
}
public double toDouble() {
return 1.0 * numer / denom;
}
//utility method
private static int greatestCommonDivisor(int a, int b) {
int c;
while (b != 0) {
c = a % b;
a = b;
b = c;
}
return Math.abs(a);
}
private static void testGcd() {
System.out.println("");
System.out.println("Test Greatest Common Denominator");
System.out.println("");
for (int i = -21; i < 31; i += 2) {
for (int j = -17; j < 31; j += 3) {
System.out.printf("\n%5d%5d%5d", i, j, greatestCommonDivisor(i, j));
}
}
System.out.println("");
}
public Rational(int numer, int denom) throws ZeroDenomException {
// CI1. No way to fix, must throw exception.
if (denom == 0) {
throw new ZeroDenomException();
}
// CI2. Can fix.
if (denom < 0) {
numer *= -1;
denom *= -1;
}
// CI3. Can fix.
int gcd = greatestCommonDivisor(numer, denom);
if (gcd != 1) {
numer /= gcd;
denom /= gcd;
}
// all class invariants now satisfied, initialize fields:
this.numer = numer;
this.denom = denom;
}
public Rational(int book) throws ZeroDenomException {
//this(integer, 1);
//this(1, book);
this(book, 1);
}
public Rational() throws ZeroDenomException {
this(0);
}
private static void testClass() throws ZeroDenomException {
System.out.println("Rational tests.");
System.out.println("");
System.out.println("Test C-tor");
System.out.println("Expected outcome: 4/25, -4/25, -4/25," + "4/25 17/1, 0/1.");
System.out.println("");
Rational rat01 = new Rational(144, 900);
Rational rat02 = new Rational(-144, 900);
Rational rat03 = new Rational(144, -900);
Rational rat04 = new Rational(-144, -900);
Rational rat05 = new Rational(17);
Rational rat06 = new Rational();
System.out.println("rat01 = " + rat01);
System.out.println("rat02 = " + rat02);
System.out.println("rat03 = " + rat03);
System.out.println("rat04 = " + rat04);
System.out.println("rat05 = " + rat05);
System.out.println("rat06 = " + rat06);
}
public static void main(String[] args) {
System.out.println("Rational class");
System.out.println("Implemented by (My Name)");
try {
testClass();
//testGcd();
} catch (ZeroDenomException ex) {
System.out.println("Zero demon exception in testClass()! (J:H)");
}
System.out.println("");
System.out.println("Try bad input");
try {
Rational rat00 = new Rational(0, 0);
} catch (ZeroDenomException zde) {
System.out.println(" Expected Zero Denominator Exception. " + zde);
} catch (Exception e) {
System.out.println("Should not be a general Exception.");
}
System.out.println("");
System.out.println("");
System.out.println("Test toDouble. Expect 0.16");
System.out.println("rat04 to double: " + rat04.toDouble());
}
}
You declared rat04 in testClass and use it in main. The scopes are different.
You can't use a variable from one scope to another.
You can create a static variable in the class (member variable) to be accessible from both method if you want (but really should not...)
public class Rational {
static Rational rat04;
...
}
Or simply don't print the value in main but in testClass where it belong.
Related
This question already has answers here:
What is a StackOverflowError?
(16 answers)
Understanding recursion [closed]
(20 answers)
Closed 3 years ago.
i'm writing a program based on the Quadratic Equation everything looks good to me and there are not syntax or logical errors from what i see and also Eclipse isn't detecting any errors before running.
this is the output from the code:
Exception in thread "main" java.lang.StackOverflowError
at QuadraticEquation.getDiscriminant(QuadraticEquation.java:33)
note it continues like this for about 50 lines or so
public class QuadraticEquation {
private double a;
private double b;
private double c;
public QuadraticEquation() {
double a = 0;
double b = 0;
double c = 0;
}
public QuadraticEquation(double newA, double newB, double newC) {
a = newA;
b = newB;
c = newC;
}
public double discriminant1 = Math.pow(b, 2) - 4 * a * c;
public double discriminant2 = Math.pow(b, 2) - 4 * a * c;
public double getA() {
return getA();
}
public double getB() {
return getB();
}
public double getC() {
return getC();
}
public double getDiscriminant() {
double discriminant = (b * 2) - (4 * a * c);
return getDiscriminant();
}
public double getRoot1() {
double r1 = (-1*b) + Math.sqrt(discriminant1) / (2*a);
return getRoot1();
}
public double getRoot2() {
double r2 = (-1*b) - Math.sqrt(discriminant2) / (2*a);
return getRoot2();
}
public void setA(double newA1) {
a = newA1;
}
public void setB(double newB1) {
b = newB1;
}
public void setC(double newC1) {
c = newC1;
}
}
import java.util.Scanner;
public class TestEquation {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
QuadraticEquation Quadratic = new QuadraticEquation();
System.out.println("Please enter the values of the following variables: ");
System.out.println("a: ");
Quadratic.setA(input.nextDouble());
System.out.println("b: ");
Quadratic.setB(input.nextDouble());
System.out.println("c: ");
Quadratic.setC(input.nextDouble());
if (Quadratic.getDiscriminant() < 0) {
System.out.println("The equation has the following roots:");
System.out.println("The first one is " + Quadratic.getRoot1());
System.out.println("The second one is " + Quadratic.getRoot2());
}
else if (Quadratic.getDiscriminant() == 0) {
System.out.println("The equation has one root:");
System.out.println(Quadratic.getRoot1());
}
else {
System.out.println("The equation has the no real roots");
return;
}
}
}
Your error is an infinite recursion here:
public double getDiscriminant() {
double discriminant = (b * 2) - (4 * a * c);
return getDiscriminant();
}
This function calls itself infinitely until the stack overflows. I believe you wanted to return the variable discriminant instead?
Same for your functions getRoot1, getRoot2, getA, getB, and getC.
I have written a polynomial class and a tester class. The polynomial class can evaluate and return the sum of the polynomial when the degree, coefficients and the value of x are provided. Basically I need to edit my toString method so it actually prints out the polynomial
import java.util.Arrays;
import java.util.Scanner;
public class Polynomial {
private int degree;
private int [] coefficient;
private double evaluation;
private double sum;
private double value;
Scanner key = new Scanner(System.in);
public Polynomial(int degree)
{
this.degree = degree;
coefficient = new int [degree+1];
}
public void setCoefficient(int coefficient)
{
this.coefficient[this.degree] = coefficient;
}
public int getCoefficient(int degree)
{
return coefficient[degree];
}
public double Evaluate(double value)
{
this.value =value;
for (int i=0; i<=degree; i++)
{
System.out.println("Enter coefficent for position " + i);
this.coefficient[i] = key.nextInt();
evaluation = Math.pow(value, i)*this.coefficient[0] ;
this.sum += evaluation;
}
return sum;
}
/** Standard toString method */
//needed something better than this below...needed an actual polynomial printed out
public String toString()
{
return "The degree of the polynomial is " + degree + " and the value for which it has been evaluated is" + value;
}
}
This should be along the lines you should be proceeding. I included the main function in your Polynomial class for simplicity, so you will have to modify that if you want to keep it in your tester class. Notice that degree has been made into an integer array of size degree +1(allocated in the constructor):
import java.util.Scanner;
public class Polynomial {
private int degree;
private int [] coefficient;
private double evaluation;
private double sum;
Scanner key = new Scanner(System.in);
public Polynomial(int degree)
{
this.degree = degree;
coefficient = new int [degree+1];
}
public void setCoefficient(int coefficient, int degree)
{
this.coefficient[degree] = coefficient;
}
public int getCoefficient(int degree)
{
return coefficient[degree];
}
public void Evaluate(double value)
{
for (int i=0; i<=degree; i++)
{
System.out.println("Enter coefficent for position " + i);
this.coefficient[i] = key.nextInt();
evaluation = Math.pow(value, i)*this.coefficient[0] ;
this.sum += evaluation;
}
}
public double getSum(){
return sum;
}
public String toString()
{
String s = "";
for (int i=0; i <= degree; i++)
{
s += coefficient[i];
switch (i) {
case 0:
s += " + ";
break;
case 1:
s += "x + ";
break;
default:
s += "x^" + i + ((i==degree)?"":" + ");
}
}
return s;
}
public static void main(String[] args) {
int degree;
double sum;
int coefficient;
Scanner key = new Scanner(System.in);
System.out.println("Enter the degree of the polynomial");
degree=key.nextInt();
Polynomial fun = new Polynomial(degree);
fun.Evaluate(3.0);
System.out.println(" The sum of the polynomial is " + fun.getSum());
System.out.println(fun);
}
}
The usual way of making the objects of a class printable is to supply a toString method in the class, which specifies how to express objects of that class as a String. Methods such as println and other ways of outputting a value will call a class's toString method if they need to print an object of that class.
You should adopt the same pattern with your Polynomial class - write a toString method with all the output logic. Then in your PolynomialTester class, all you need to write is System.out.println(fun); and the rest will just happen. You'll find this far more versatile than writing a method that actually does the printing. For example, you'll be able to write something like
System.out.println("My polynomial is " + fun + " and " + fun + " is my polynomial.");
if that's your idea of fun.
A few other things concern me about your class.
You seem to be only storing one coefficient and one exponent. I'd expect a polynomial to have a whole array of coefficients.
You have fields for evaluation and sum - but these only really make sense while a polynomial is being evaluated. They're not long-term properties of the polynomial. So don't store them in fields. Have them as local variables of the evaluate method, and return the result of the evaluation.
I'd expect a class like this to be immutable. That is, you should provide all the coefficients when the object is created, and just never change them thereafter. If you do it that way, there's no need to write setter methods.
So I've written my own version of your class, that fixes those issues listed above, and implements a toString method that you can use for printing it. A second version of toString lets you specify which letter you want to use for x. I've used "varargs" in the constructor, so you can construct your polynomial with a line such as
Polynomial fun = new Polynomial (7, 2, 5, 0, 1);
specifying the coefficients from the constant term through in order to the coefficient of the term with the highest exponent. Or you can just pass an array.
See that I've changed the logic a wee bit - my version prints the polynomial in the conventional order, from highest to lowest exponent. It leaves off the decimals if the coefficient is an integer. It doesn't print a 1 in front of an x. And it deals cleanly with - signs.
import java.util.Arrays;
public class Polynomial {
private double[] coefficients;
public Polynomial(double... coefficients) {
this.coefficients = Arrays.copyOf(coefficients, coefficients.length);
}
public int getDegree() {
int biggestExponent = coefficients.length - 1;
while(biggestExponent > 0 && coefficients[biggestExponent] == 0.0) {
biggestExponent--;
}
return biggestExponent;
}
public double getCoefficient(int exponent) {
if (exponent < 0 || exponent > getDegree()) {
return 0.0;
} else {
return coefficients[exponent];
}
}
public double evaluateAt(double x) {
double toReturn = 0.0;
for (int term = 0; term < coefficients.length; term++) {
toReturn += coefficients[term] * Math.pow(x, term);
}
return toReturn;
}
#Override
public String toString() {
return toString('x');
}
public String toString(char variable) {
boolean anythingAppendedYet = false;
StringBuilder toReturn = new StringBuilder();
for (int exponent = coefficients.length - 1; exponent >= 0; exponent--) {
if (coefficients[exponent] != 0.0) {
appendSign(toReturn, exponent, anythingAppendedYet);
appendNumberPart(toReturn, exponent);
appendLetterAndExponent(toReturn, exponent, variable);
anythingAppendedYet = true;
}
}
if (anythingAppendedYet) {
return toReturn.toString();
} else {
return "0";
}
}
private void appendSign(StringBuilder toAppendTo, int exponent, boolean anythingAppendedYet) {
if (coefficients[exponent] < 0) {
toAppendTo.append(" - ");
} else if (anythingAppendedYet) {
toAppendTo.append(" + ");
}
}
private void appendNumberPart(StringBuilder toAppendTo, int exponent) {
double numberPart = Math.abs(coefficients[exponent]);
if (numberPart != 1.0 || exponent == 0) {
//Don't print 1 in front of the letter, but do print 1 if it's the constant term.
if (numberPart == Math.rint(numberPart)) {
// Coefficient is an integer, so don't show decimals
toAppendTo.append((long) numberPart);
} else {
toAppendTo.append(numberPart);
}
}
}
private void appendLetterAndExponent(StringBuilder toAppendTo, int exponent, char variable) {
if (exponent > 0) {
toAppendTo.append(variable);
}
if (exponent > 1) {
toAppendTo.append("^");
toAppendTo.append(exponent);
}
}
}
So I tested it with this class
public class PolynomialTester {
public static void main(String[] args) {
Polynomial fun = new Polynomial (7, 2, 5, 0, 1);
System.out.println(fun.getDegree());
System.out.println(fun.evaluateAt(3));
System.out.println(fun);
}
}
and the output was
4
139.0
x^4 + 5x^2 + 2x + 7
then I realised that you wanted to be able to input the coefficients in a loop. So I changed PolynomialTester to this. See how I build the array and then create the object.
import java.util.Scanner;
public class PolynomialTester {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the degree:");
int degree = input.nextInt();
double[] coefficients = new double[degree + 1];
for( int exponent = 0; exponent <= degree; exponent++) {
System.out.println("Enter the coefficient of x^" + exponent);
coefficients[exponent] = input.nextDouble();
}
Polynomial fun = new Polynomial (coefficients);
System.out.println(fun.evaluateAt(3));
System.out.println(fun);
input.close();
}
}
Note that if you really want your polynomial to be printed in "reverse" order, with the constant term first, you could change the loop in the toString method to this.
for (int exponent = 0; exponent < coefficients.length; exponent++) {
You may add a class member String poly, then modify the following method.
public void Evaluate(double value)
{
for (int i=0; i<=degree; i++)
{
System.out.println("Enter coefficent for position " + i);
this.coefficient= key.nextInt();
evaluation = Math.pow(value, i)*coefficient ;
this.sum += evaluation;
this.poly = "";
if(coefficient != 0)
{
if(i > 0)
{
this.poly += " + " + Integer.toString(coefficient) + "x^" + Integer.toString(i); // you may replace x with the actual value if you want
}
else
{
this.poly = Integer.toString(coefficient)
}
}
}
}
How can I create a java program using only if / else to order 3 numbers in descending order. I can not use for processes or array. Numbers are entered by the user.
Here's what i have so far. What should i do, is the user enters two integers that are the same? The code can only display one output.
import java.util.Scanner;
public class DescendingOrder
{
public static void main(String [] args)
{
//variable dec.
int a;
int b;
int c;
Scanner kbd = new Scanner(System.in);
//user prompt
System.out.println("Please enter three integers");
a=kbd.nextInt();
b=kbd.nextInt();
c=kbd.nextInt();
//program output
if (a>=b && b>=c && a>=c)
{
System.out.println("a b c");
}
if (a>=c && c>=b && a>=b )
{
System.out.println("a c b");
}
if (b>=a && a>=c && b>=c)
{
System.out.println("b a c");
}
if (b>=c && c>=a && b>=c)
{
System.out.println("b c a");
}
if(c>=a && a>=b && c>=b)
{
System.out.println("c a b");
}
if (c>= b && b>=a && c>=a)
{
System.out.println("c b a");
}
}
}
A simpler way you can do it is
if (a < b)
{
int temp = a;
a = b;
b = temp;
}
if (b < c)
{
int temp = b;
b = c;
c = temp;
}
if (a < b)
{
int temp = a;
a = b;
b = temp;
}
System.out.println(a + " " + b + " " + c);
If two numbers are the same it doesn't really matter, as 90 45 45 is the same as 90 45 45. (In the case of your code as written, however, you are correct in noticing that it does matter. You could fix this by changing all your if statements except the first one into else-if)
This question seems to be a thought exercise so consider this answer an alternative to the other correct answers for your consideration. Here my enterprise-y solution.
Step 0, refactor your code to make it testable and stub out the method that will do the actual work:
import static java.lang.System.in;
import static java.lang.System.out;
import java.util.Scanner;
public class DescendingOrder {
public static final void main(final String... args) { // unavoidable use of an array, please don't dock points
try (final Scanner kbd = new Scanner(in)) { // always close your Closeables
final int a = kbd.nextInt();
final int b = kbd.nextInt();
final int c = kbd.nextInt();
final DescendingOrder calculator = new DescendingOrder();
out.println(calculator.order(a, b, c));
}
}
public String order(final int a, final int b, final int c) {
return null;
}
}
Step 1, write a unit test:
import static java.lang.Integer.MAX_VALUE;
import static java.lang.Integer.MIN_VALUE;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
public class DescendingOrderTest {
private DescendingOrder orderer;
#Before
public void setUp() throws Exception {
orderer = new DescendingOrder();
}
#Test
public final void testOrderABC() {
final String result = orderer.order(MAX_VALUE, 0, MIN_VALUE); // don't forget the edge cases
assertEquals(MAX_VALUE + " " + 0 + " " + MIN_VALUE, result);
}
#Test
public final void testOrderACB() {
final String result = orderer.order(13, 5, 8);
assertEquals("13 8 5", result);
}
#Test
public final void testOrderBAC() {
final String result = orderer.order(4, 8, 2);
assertEquals("8 4 2", result);
}
#Test
public final void testOrderBCA() {
final String result = orderer.order(-8, -2, -4); // don't forget negative numbers
assertEquals("-2 -4 -8", result);
}
#Test
public final void testOrderCAB() {
final String result = orderer.order(1, -5, 5);
assertEquals("5 1 -5", result);
}
#Test
public final void testOrderCBA() {
final String result = orderer.order(MAX_VALUE, 0, MIN_VALUE);
assertEquals(MAX_VALUE + " " + 0 + " " + MIN_VALUE, result);
}
#Test
public final void testAllSame() {
final String result = orderer.order(53, 53, 53);
assertEquals("53 53 53", result);
}
}
Step 2, iteratively implement order until your tests pass:
public String order(final int a, final int b, final int c) {
if (a > b && a > c) {
return a + " " + order(b, c);
} else if (b > a && b > c) {
return b + " " + order(a, c);
}
return c + " " + order(a, b);
}
protected String order(final int x, final int y) {
if (x > y) {
return x + " " + y;
}
return y + " " + x;
}
It might not be the most computationally efficient, but I kept the method sizes small so it is clear what the code is meant to accomplish. I also do not need to scan through six scenarios to see that it is correct. If I assume that order( int, int ) is correct, then I only need to work through three scenarios to see that order( int, int, int ) is correct.
Obviously, this is overkill. But those constraints would never really exist.
I think your code was fine you were just printing wrong. You have to understand that a,b,c are variable of type int. when you use the + operator with two ints it performs an addition. If you use the + operator with an int and with a string it produces a concatenation. The int 'calls' to string turning the int into a string which produces String + String = concatenation.
Anyways, I think this is what you wanted. Let me know if this is what you wanted.
import java.util.Scanner;
public class Stackoverflow
{
public static void main(String [] args)
{
//variable dec.
int a;
int b;
int c;
Scanner kbd = new Scanner(System.in);
//user prompt
System.out.println("Please enter three integers");
a=kbd.nextInt();
b=kbd.nextInt();
c=kbd.nextInt();
//program output
if (a>=b && b>=c && a>=c)
{
System.out.println(a+" "+b+" "+c);
}
if (a>=c && c>=b && a>=b )
{
System.out.println(a+" "+c+" "+b);
}
if (b>=a && a>=c && b>=c)
{
System.out.println(b+" "+a+" "+c);
}
if (b>=c && c>=a && b>=c)
{
System.out.println(b+" "+c+" "+a);
}
if(c>=a && a>=b && c>=b)
{
System.out.println(c+" "+a+" "+b);
}
if (c>= b && b>=a && c>=a)
{
System.out.println(c+" "+b+" "+a);
}
}
}
My Professor has created code that needs to be modified. The only problem is I don't understand his style at all on top of being a fairly new programmer myself. The parameters for the assignment are as follows:
• Modify setters so that they ignore inappropriate values (i.e., divide by zero)
• Implement the equals() method inherited from the top-level Object class
• Implement less than and greater than methods
• Implement add, subtract, and multiply methods
• Makes sure the equals method returns true for any two fractions that are arithmetically equal.
• Make sure that the equals method does not alter the values of the fractions being compared.
• The lessThan and greaterThan methods must each return a Boolean value, not a string.
• The provided reduce method returns a new (reduced) fraction object as its function value
I am completely lost about this assignment as I don't have the slightest clue where to even begin. Any and all help would be greatly appreciated!!!! I have the feeling that once I see it done, it will all make sense to me. I am just not used to this style of teaching at all.
public class Fraction {
private int numer;
private int denom;
public Fraction() { // no-arg constructor
numer = 0;
denom = 1;
}
public Fraction(int numer, int denom) {
this.numer = numer;
this.denom = denom;
}
public Fraction(Fraction frac) { // copy constructor
numer = frac.getNumer();
denom = frac.getDenom();
}
// getters and setters
public int getNumer() {
return numer;
}
public void setNumer(int x) {
numer = x;
}
public int getDenom() {
return denom;
}
public void setDenom(int x) {
denom = x;
}
// Special Methods
public String toString() {
return numer + "/" + denom;
}
// Other Methods
public Fraction reduce() {
Fraction temp = new Fraction();
int GCD = gcd(numer, denom);
temp.setNumer(numer / GCD);
temp.setDenom(denom / GCD);
return temp;
}
// Private Methods
private int gcd(int n1, int n2)
{
int M, N, R;
if (n1 < n2)
{
N = n1;
M = n2;
}
else
{
N = n2;
M = n1;
}
R = M % N;
while (R != 0)
{
M = N;
N = R;
R = M % N;
}
return N;
}
public static void main(String[] args) {
// test constructors
Fraction frac0 = new Fraction();
System.out.println("TESTING NO-ARG CONSTRUCTOR");
System.out.println("frac0: Result should be 0/1:");
System.out.println("Numer = " + frac0.getNumer());
System.out.println("Denom = " + frac0.getDenom());
System.out.println("TESTING int/int CONSTRUCTOR");
Fraction frac1 = new Fraction(2,4);
System.out.println("frac1: Result should be 2/4:");
System.out.println("Numer = " + frac1.getNumer());
System.out.println("Denom = " + frac1.getDenom());
System.out.println("TESTING Fraction CONSTRUCTOR");
Fraction frac2 = new Fraction(frac1);
System.out.println("frac2: Result should be 2/4:");
System.out.println("Numer = " + frac2.getNumer());
System.out.println("Denom = " + frac2.getDenom());
System.out.println("TESTING COPY CONSTRUCTOR frac1 frac2");
if (frac1.getNumer() == frac2.getNumer() &&
frac1.getDenom() == frac2.getDenom() &&
frac1 != frac2)
{
System.out.println("Copy constructor working");
}
else
System.out.println("PROBLEM with copy constructor");
// test equal method
System.out.println("TESTING EQUALITY OF frac1 and frac2 -");
System.out.println("SHOULD BE FOUND EQUAL:");
if (frac1.equals(frac2))
{
System.out.println("frac1 and frac2 found equal");
}
else
{
System.out.println("frac1 and frac2 NOT equal");
}
// test reduce method
System.out.println("TESTING reduce METHOD ON frac1");
Fraction reduced_frac1 = frac1.reduce();
System.out.println("Reduced frac1 = " + reduced_frac1);
// test getters and setters
frac2.setNumer(8);
frac2.setDenom(12);
System.out.println("Numer = " + frac2.getNumer());
System.out.println("Denom = " + frac2.getDenom());
// System.out.println("GCD of 2/4 = " + frac1.gcd(1,4));
}
//* TO BE COMPLETED *
}
There is nothing wrong with his teaching methods and with some further study I am sure you can figure it out. No one here is going to do it for you and I don't want to do your homework so I will ask the common question, what have you tried so far? I've given you one of the modified setters. Keep working, study your java better or you are going to have a hard time when it gets difficult.
//Here is where you start
public void setDenom(int x){
if(x > 0){
denom = x;
}else{
//throw an error
}
}
I'm solving Uva's 3n+1 problem and I don't get why the judge is rejecting my answer. The time limit hasn't been exceeded and the all test cases I've tried have run correctly so far.
import java.io.*;
public class NewClass{
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
int maxCounter= 0;
int input;
int lowerBound;
int upperBound;
int counter;
int numberOfCycles;
int maxCycles= 0;
int lowerInt;
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
String line = consoleInput.readLine();
String [] splitted = line.split(" ");
lowerBound = Integer.parseInt(splitted[0]);
upperBound = Integer.parseInt(splitted[1]);
int [] recentlyused = new int[1000001];
if (lowerBound > upperBound )
{
int h = upperBound;
upperBound = lowerBound;
lowerBound = h;
}
lowerInt = lowerBound;
while (lowerBound <= upperBound)
{
counter = lowerBound;
numberOfCycles = 0;
if (recentlyused[counter] == 0)
{
while ( counter != 1 )
{
if (recentlyused[counter] != 0)
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
else
{
if (counter % 2 == 0)
{
counter = counter /2;
}
else
{
counter = 3*counter + 1;
}
numberOfCycles++;
}
}
}
else
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
recentlyused[lowerBound] = numberOfCycles;
if (numberOfCycles > maxCycles)
{
maxCycles = numberOfCycles;
}
lowerBound++;
}
System.out.println(lowerInt +" "+ upperBound+ " "+ (maxCycles+1));
}
}
Are you making sure to accept the entire input? It looks like your program terminates after reading only one line, and then processing one line. You need to be able to accept the entire sample input at once.
I faced the same problem. The following changes worked for me:
Changed the class name to Main.
Removed the public modifier from the class name.
The following code gave a compilation error:
public class Optimal_Parking_11364 {
public static void main(String[] args) {
...
}
}
Whereas after the changes, the following code was accepted:
class Main {
public static void main(String[] args) {
...
}
}
This was a very very simple program. Hopefully, the same trick will also work for more complex programs.
If I understand correctly you are using a memoizing approach. You create a table where you store full results for all the elements you have already calculated so that you do not need to re-calculate results that you already know (calculated before).
The approach itself is not wrong, but there are a couple of things you must take into account. First, the input consists of a list of pairs, you are only processing the first pair. Then, you must take care of your memoizing table limits. You are assuming that all numbers you will hit fall in the range [1...1000001), but that is not true. For the input number 999999 (first odd number below the upper limit) the first operation will turn it into 3*n+1, which is way beyond the upper limit of the memoization table.
Some other things you may want to consider are halving the memoization table and only memorize odd numbers, since you can implement the divide by two operation almost free with bit operations (and checking for even-ness is also just one bit operation).
Did you make sure that the output was in the same order specified in the input. I see where you are swapping the input if the first input was higher than the second, but you also need to make sure that you don't alter the order it appears in the input when you print the results out.
ex.
Input
10 1
Output
10 1 20
If possible Please use this Java specification : to read input lines
http://online-judge.uva.es/problemset/data/p100.java.html
I think the most important thing in UVA judge is 1) Get the output Exactly same , No Extra Lines at the end or anywhere . 2) I am assuming , Never throw exception just return or break with No output for Outside boundary parameters.
3)Output is case sensitive 4)Output Parameters should Maintain Space as shown in problem
One possible solution based on above patterns is here
https://gist.github.com/4676999
/*
Problem URL: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
Home>Online Judge > submission Specifications
Sample code to read input is from : http://online-judge.uva.es/problemset/data/p100.java.html
Runtime : 1.068
*/
import java.io.*;
import java.util.*;
class Main
{
static String ReadLn (int maxLg) // utility function to read from stdin
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main (String args[]) // entry point from OS
{
Main myWork = new Main(); // create a dinamic instance
myWork.Begin(); // the true entry point
}
void Begin()
{
String input;
StringTokenizer idata;
int a, b,max;
while ((input = Main.ReadLn (255)) != null)
{
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
if (a<b){
max=work(a,b);
}else{
max=work(b,a);
}
System.out.println (a + " " + b + " " +max);
}
}
int work( int a , int b){
int max=0;
for ( int i=a;i<=b;i++){
int temp=process(i);
if (temp>max) max=temp;
}
return max;
}
int process (long n){
int count=1;
while(n!=1){
count++;
if (n%2==1){
n=n*3+1;
}else{
n=n>>1;
}
}
return count;
}
}
Please consider that the integers i and j must appear in the output in the same order in which they appeared in the input, so for:
10 1
You should print
10 1 20
package pandarium.java.preparing2topcoder;/*
* Main.java
* java program model for www.programming-challenges.com
*/
import java.io.*;
import java.util.*;
class Main implements Runnable{
static String ReadLn(int maxLg){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main(String args[]) // entry point from OS
{
Main myWork = new Main(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
private String input;
private StringTokenizer idata;
private List<Integer> maxes;
public void run(){
String input;
StringTokenizer idata;
int a, b,max=Integer.MIN_VALUE;
while ((input = Main.ReadLn (255)) != null)
{
max=Integer.MIN_VALUE;
maxes=new ArrayList<Integer>();
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
System.out.println(a + " " + b + " "+max);
}
}
private static int getCyclesCount(long counter){
int cyclesCount=0;
while (counter!=1)
{
if(counter%2==0)
counter=counter>>1;
else
counter=counter*3+1;
cyclesCount++;
}
cyclesCount++;
return cyclesCount;
}
// You can insert more classes here if you want.
}
This solution gets accepted within 0.5s. I had to remove the package modifier.
import java.util.*;
public class Main {
static Map<Integer, Integer> map = new HashMap<>();
private static int f(int N) {
if (N == 1) {
return 1;
}
if (map.containsKey(N)) {
return map.get(N);
}
if (N % 2 == 0) {
N >>= 1;
map.put(N, f(N));
return 1 + map.get(N);
} else {
N = 3*N + 1;
map.put(N, f(N) );
return 1 + map.get(N);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
while(scanner.hasNextLine()) {
int i = scanner.nextInt();
int j = scanner.nextInt();
int maxx = 0;
if (i <= j) {
for(int m = i; m <= j; m++) {
maxx = Math.max(Main.f(m), maxx);
}
} else {
for(int m = j; m <= i; m++) {
maxx = Math.max(Main.f(m), maxx);
}
}
System.out.println(i + " " + j + " " + maxx);
}
System.exit(0);
} catch (Exception e) {
}
}
}