Scope, method return - java

I been trying to write a program that can display the fibonacci sequence. However any number I input will output 0. I suspect that it has either to do with scope of the variable or something wrong with my return. could someone look at my code and figure out if it is really those problems? I'm sorta new to java, so even the basic is difficult for me.
public static void main(String args [])
{
Scanner in = new Scanner(System.in);
int number = 0;
do{
System.out.print("Which Fibonacci Number would you like? ");
fib = in.nextInt();
}while(number < 0 || number > 71);
System.out.print("Fibonacci #"+number+" is "+fibcalc(fib)+"\n");
}
public static double fibcalc(double number)
{
double prevNumber1 = 0;
double prevNumber2 = 1;
double fib = 0;
for(int i =0; i < number; i++){
fib = prevNumber1;
prevNumber1 = prevNumber2;
prevNumber2 = fib + prevNumber2;
}
return fib;
}
made some revisions, down to one error.
error: cannot find symbol
System.out.print("Fibonacci #"+number+" is "+fibcalc(fib)+"\n");
symbol: variable fib
I got a qucik question.
can one method call upon another method for a variable? the variable is inside of the curly braces. kind of what I have in my code.it seems like most of my errors were similar to this one.

It's nothing to do with scope. Look at this code:
while(i < fib){
fib = prevNumber1;
...
}
You're using the fib variable as both "the number of iterations to execute" and "the current result". Those are two separate concepts, and should be stored in separate variables.
In particular, on the first iteration, fib will be set to 0 and i will be incremented to 1... so your loop will then terminate, returning 0.
I'd also suggest changing your parameter type to int and using long or BigInteger for the Fibonacci number variables (depending on what range you want to support). There's no part of this problem which needs non-integer values, so you shouldn't be using double at all.
Finally, I'd suggest using a for loop instead of a while loop - you want to perform a given number of iterations, and the idiomatic way of writing that in Java is:
for (int i = 0; i < count; i++) {
// whatever
}

Related

Java - my while loop works, but my for loop doesn't - having trouble converting it

I assume that if I can't convert my while loop into a for loop, then I don't fully understand the concepts here. Here's my working while loop:
(I am trying to implement a program, which calculates the sum 1+2+3+...+n where n is given as user input.)
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a number: ");
int number = Integer.valueOf(scanner.nextLine());
int sum = 0;
int i = 0;
while (i < number) {
i++;
sum += i;
}
System.out.println(sum);
I was looking at this user's answer here: https://stackoverflow.com/a/36023451/11522261
and tried to implement it, but it's not working.
.....
for (i = 0; i < number; i++){
sum += i;
}
System.out.println(sum);
It looks like the conditions of For Init expression statement and ForUpdate are set right, but I'm having trouble understanding the differences here.
Also, it looks like this exercise is trying to teach loops to solve iterative problems. But I suspect that this isn't helping me practice recursion. Perhaps there is a recursive solution to this problem which would be better. Just thinking out loud here. Thanks!
The difference is that in your while loop, you're incrementing i before adding it to sum, but in your for loop, it's after.
If the while is producing the right result, you can adjust your for by starting at 1 instead of 0 and continuing while <= number instead of < number.
For completeness, here's how your current for loop works:
i = 0
If i < number is not true, exit the loop; otherwise, continue to Step 3
sum += i (i is still 0)
i++
Goto Step 2
On the second pass, i < number is 1 < number so still true if number is greater than 1, so you go to Step 3, do sum += i while i is 1, then continue.
Eventually i < number isn't true anymore, and the loop exits.
For problems like this, the best approach is usually to use the debugger built into your IDE to step through the code statement by statement, looking at the values of variables as you go. That can reveal how things work really well. This article may be helpful: How to debug small programs
Since you are incrementing the value of i before adding it to sum in the while loop, the same thing needs to be done in case of for loop as well. Given below is the implementation using the for loop:
for (i = 0; i++ < number; ){
sum += i;
}
System.out.println(sum);
Use <= instead of <. This will solve Your problem, and make sure you understand why will the following code would work. I would recommand you to use a paper and pencil and start writing down the values of i and sum after every iteration.
for (i = 1; i <= number; i++) {
sum += i;
}

for loop won't run inside while loop java

There's a while loop in my program that will loop infinitely because the for loop inside won't run twice. I want to find the number of combinations that will have a sum of 4 from input and here's my code:
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
ArrayList<Integer> taxi = new ArrayList<Integer>();
for (int i=0; i<n; i++) {
taxi.add(scan.nextInt());
}
int i = 0;
int total=0;
int tax=0;
int num = 0;
while (num<n) {
i=0;
for (i=0; i<n; i++) {
if (total+taxi.get(i)<=4) {
total+=taxi.get(i);
System.out.println(total);
num++;
}
}
tax++;
}
System.out.println("Taxis= " + tax);
looking though you're code it seems your issue lies in the usage of some of your variables such as I multiple times which causes the code to not compile. try using better names or more unique names in order to prevent these issues in future. as well as that I would also advise not zeroing all of your variables so often in such a manner. Finally your issue has to do with your usage of the variable n as it remains a fixed number which will not change in the while loop meaning it will always be true. the best way to fix this is to utilize the
break;
command to exit the while loop or to use a counted loop like a for loop.
In my honest opinion i would request that when asking these questions next time check all the variables with a print line in the appropriate spot.

Range in Array Java

I need to complete this task. But I am not entirely sure how to get the range into the array. I think I am supposed to use a loop somehow but I do not get it to work.
This is what I have so far:
import java.util.*;
public class A2_1
{
static Scanner x = new Scanner(System.in);
public static void main(String[] args)
{
int [] myArray = new int [1000000];
int x;
for ( x = 0; x <= 100; x++)
{
myArray [x] = x+1;
}
System.out.println(myArray);
}
}
This is the task:
"Create a program that generates 1,000,000 integer random values in the range of [1,..,100] and for any given x (between 1 and 100) taken from the user input computes "(๐‘‡๐‘œ๐‘ก๐‘Ž๐‘™ ๐‘›๐‘ข๐‘š๐‘๐‘’๐‘Ÿ ๐‘œ๐‘“ ๐‘’๐‘™๐‘’๐‘š๐‘’๐‘›๐‘ก๐‘  ๐‘™๐‘’๐‘ ๐‘  ๐‘กโ„Ž๐‘Ž๐‘› ๐‘œ๐‘Ÿ ๐‘’๐‘ž๐‘ข๐‘Ž๐‘™ ๐‘ก๐‘œ ๐‘ฅ)/1,000,000".
This value must be comparable to the CDF of a uniform distribution U[1,100] at point x."
Im not going to give you the answer since this sounds like homework but I will help you break it down into manageable chunks.
First, generate 1000000 random numbers between 1 and 100. You were on the right track and combine it with Dawnkeepers hint. int[] randoms = new int[1000000]; is an int array with a size of 1000000. Now iterate over each index and assign it a random number(see above). Now you have an array with a million random numbers. Generating a million randoms can be a lengthy procedure depending on you machine, so yea.
Next, use the Scanner class to get the users input.(pro tip: dont use the same variable name for your scanner as your variable in the for loop lol). Now do an if check to make sure they enter a number between 1 and 100. if(val > 0 && val <= 100). If this passes, move on, else quit or prompt for user to give a new input. Using the scanner is pretty trivial so I wont go into this.
Finally, iterate through your list of randoms and keep a counter of how many numbers less then or equal to x.
int counter = 0;
for(int i = 0; i < randoms.length; i++) {
//if randoms[i] is less then or equal x, counter++
}
Take that counter and do your math, int final_answer = counter/randoms.length;
That's all that is to it. There are more efficient ways of doing this but I tried to make it simple to follow. If I misread the question, sorry.

Why doesn't my program that computes perfect numbers print anything?

I got an assignment to create a program which displays the perfect integers between one and 100. Here is the actual assignment:
Create a PerfectIntegers application that displays all perfect integers up to 100. A perfect integer is a number which is equal to the sum of all its factors except itself. For example, 6 is a perfect number because 1 + 2 + 3 = 6. The application should include a boolean method isPerfect().
I tried and came up with this:
import java.util.ArrayList;
public class PerfectIntegers {
public static boolean isPerfect(int a){
ArrayList<Integer> factors = new ArrayList<Integer>();
int sum=0;
boolean is;
for (int i=1; i<=100; i++){
double r=a/i;
if (r%1==0){
factors.add(i);
}
}for (int i=0;i<factors.size();i++){
sum+=factors.get(i);
}if (sum==a){
is=true;
}else{
is=false;
}return is;
}
public static void getInts(){
for (int i=2; i<=100; i++){
boolean is=isPerfect(i);
if (is!=false){
System.out.print(i+" ");
}
}
}
public static void main(String[] args) {
getInts();
}
}
Eclipse did not show any errors but when I try to run it, the program is terminated and I get nothing.
The problem is likely with double r, as it is not dividing properly 100% of the time.
Your factorization code is wrong. You can fix it like this:
for (int i = 1 ; i < a; i++) {
if (a % i == 0) {
factors.add(i);
}
}
One reason your old code did not work is that you misunderstood the workings of the % operator. It computes the remainder of the division of the left-hand side by the right-hand side, so r % 1 == 0 will be true for all numbers, because 1 divides everything; r % 2 == 0 is a way to detect even numbers, and so on.
The other reason is that you went all the way to 100 in search of divisors. This necessarily includes a, which automatically puts the total above the number itself, because 1 is already on the list.
Once you get this working, you could simplify the code by dropping the list of factors. Since the sum of all factors is all that you need, you might as well compute it in the factorization loop, and drop the loop that follows it:
sum = 0;
for (int i = 1 ; i < a; i++) {
if (a % i == 0) {
sum += i;
}
}
dasblinkenlight has already provided the correct answer. Let me just add that since this seems to be a (potentially graded) assignment you might consider refactoring the getInts() method as well.
boolean is=isPerfect(i);
if (is!=false){
System.out.print(i+" ");
}
is actually equal to
if (isPerfect(i)){
System.out.print(i+" ");
}
since isPerfect() already returns a boolean that can be used inside the condition of the if-statement.
It can be argued (even though I strongly disagree in this concrete case) that it might be more readable to first store the return value in a variable like in in the first variation. But even then you should never have to check for
if (is!=false) { //...
but should be using
if (is) { // ...
instead.

Java Double Array

I'm having trouble setting up and placing values into an array using a text file containing the floating point numbers 2.1 and 4.3 each number is separated by a space - below is the error I'm getting:
Exception in thread "main" java.util.NoSuchElementException
import java.util.*;
import java.io.*;
public class DoubleArray {
public static void main(String[] args) throws FileNotFoundException {
Scanner in = new Scanner(new FileReader("mytestnumbers.txt"));
double [] nums = new double[2];
for (int counter=0; counter < 2; counter++) {
int index = 0;
index++;
nums[index] = in.nextDouble();
}
}
}
Thanks, I'm sure this isn't a hard question to answer... I appreciate your time.
You should always use hasNext*() method before calling next*() method
for (int counter=0; counter < 2; counter++) {
if(in.hasNextDouble(){
nums[1] = in.nextDouble();
}
}
but I think you are not doing the right, I'd rather
for (int counter=0; counter < 2; counter++) {
if(in.hasNextDouble(){
nums[counter] = in.nextDouble();
}
}
NoSuchElementException is thrown by nextDouble method #see javadoc
I would suggest printing the value of index out immediately before you use it; you should spot the problem pretty quickly.
It would appear you're not getting good values from your file.
Oli is also correct that you have a problem with your index, but I would try this to verify you're getting doubles from your file:
String s = in.next();
System.out.println("Got token '" + s + "'"); // is this a double??
double d = Double.parseDouble(s);
EDIT: I take this partly back...
You simply don't have tokens to get. Here's what next double would have given you for exceptions:
InputMismatchException - if the next token does not match the Float
regular expression, or is out of range
NoSuchElementException - if the input is exhausted
IllegalStateException - if this scanner is closed
I did not understand what you are trying to do in your loop ?
for (int counter=0; counter < 2; counter++) {
int index = 0;
index++; <--------
nums[index] = in.nextDouble();
}
You are declaring index = 0 then incrementing it to 1 and then using it.
Why are you not writing int index = 1; directly ?
Because it is getting declared to be zero each time loop is run and then changes value to 1.
Either you should declare it out side the loop.
You should initialize index outside of your for loop.
int index = 0;
for (int counter=0; counter < 2; counter++)
{
index++;
nums[index] = in.nextDouble();
}
Your index was getting set to zero at the beginning of each iteration of your for loop.
EDIT:
You also need to check to make sure you still have input.
int index = 0;
for (int counter=0; counter < 2; counter++)
{
if(!in.hasNextDouble())
break;
index++;
nums[index] = in.nextDouble();
}
Every time the cycle does an iteration, it's declaring the variable index and then you increase index with index++. Instead of using index, use counter, like this: num [counter] = in.nextDouble().
Check your mytestnumbers.txt file and ensure that the data that you are trying to scan is in the correct format. The exception that you are getting implies it is not.
Keep in mind that in.nextDouble() will be searching for double numbers separated by white space. In other words, "4.63.7" is not equal to "4.6 3.7" โ€” the space is required. (I do not remember off the top of my head, but I believe that nextDouble() will only search for numbers containing a decimal point, so I do not believe that "4" is equal to "4.0". If you are seeking decimal numbers with this method, then you should have decimal numbers in your file.)

Categories

Resources