My program is supposed to check if an integer is in a random integer. It will return true or false. For example: 45903 contains 4: true. For some reason; my code kept running after i entered the digit. Some thing is wrong with my containDigit() method but i can't seem to figure out. i'm very new to boolean.
import java.util.Scanner;
import java.util.*;
public class checkNum {
public static void main(String[] args) {
// Create a new Scanner object
Scanner console = new Scanner(System.in);
// Create a new Random objects
Random rand = new Random();
// Declare a integer value that is getting the value in the range of[10000, 99999]
int randomNum = rand.nextInt(90000)+10000;
// Show the random value to user by using of System.out.println
System.out.println(randomNum);
// Type a prompt message as "Enter a digit"
System.out.println("Enter a digit: ");
// Assign user input to integer value
int digit = console.nextInt();
// Define a boolean value that is assigned by calling the method "containDigit(12345,5)"
// Show the output
System.out.println(randomNum+ " contains" +
digit+" " + containDigit(randomNum,digit));
}
public static boolean containDigit(int first, int second) {
int digi = 10000;
// Define all statements to check digits of "first"
while (first > 0) {
digi = first % 10;
digi = first / 10;
}
if (digi == second){
return true;
}else {
return false;
}
// If it has "second" value in these digits, return true,
// If not, return false
// return a boolean value such as "return false";
return false;
}
}
If you're not restricted with way of solution, I can suggest below:
return (randomInt + "").contains(digit + "");
I dont understand why are you assigning first %10to digi and then immediately overwriting digi with first / 10.
Your while loop may never exit as first might always be greater than 0. It might never be entered as first might be equal to 0. You might want to do this:
while (first/10 == 0) {
first = first % 10;
if (first == second)
return true;
}
if(first%10 == second)
return true;
return false;
Your while loop never exits:
while (first > 0) {
digi = first % 10;
first = first / 10; // i believe this should be first instead of digit
}
You should add a simple print statement to check what your digit and first variables' values are:
System.out.println("digi: "+digi);
System.out.println("first: "+first);
Related
I'm trying to learn java, and I can't seem to understand recursion. I can understand how recursion can be used to add and do other basic math operations but how can recursion be used to reverse manipulate integers and individual integer digits.
example:
a method takes a single positive integer argument and displays its base five equivalent. 231 returns 1411 but the code below returns 1141. how would I reverse the order of integers put out?
public void base5(int n){
int rem=n%5;
int vis=n/5;
if(n!=0){
// System.out.print(rem/*+"|"*/);
//
// rem=(rem+rem)*10;
// System.out.print("\n||"+n+"||\n");
System.out.print(rem);
base5(vis);
}
else{
return;
}
}
The algorithm for getting individual digits of an integer, from right to left, is well known. See How to get the separate digits of an int number?.
I won't "explain" recursion, but I'll give you one possible solution for first problem:
a method takes a single positive integer and displays it with commas
inserted every three digits
import java.util.Scanner;
class Main {
public static void main( String [] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter your positive integer: ");
long number = sc.nextLong();
String result = addCommas(number);
System.out.println(result);
}
public static String addCommas(long num) {
return addCommas(num, 1);
}
public static String addCommas(long num, int counter) {
if (num == 0) {
return ""; // base case ends recursion
}
else {
long digit = num % 10;
num = num / 10;
String comma = (counter%3==0 && num>0) ? "," : "";
// recursive call below because we call addCommas() again
return addCommas(num, counter+1) + comma + digit;
}
}
}
Here's a compact solution to the second problem:
a method takes a single positive integer and displays the result of
reversing its digits
public static String reverseDigits(long num) {
if (num == 0) {
return "";
}
else {
return String.valueOf(num % 10) + reverseDigits(num / 10);
}
}
I'm doing an assignment for school that requires us to find the largest of ten numbers. The numbers are between 0-9. I believe I got that part down. My problem is I'm trying to add an extra feature that is not required for the assignment. I am trying to get the loop to completely restart after the boolean statement is false and gives an error message. After I type the invalid value in, it gives the error message, but after I press "ok" it continues on to the next number. I want it to start back at the beginning of the loop.
Here's the code:
package Largest;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class LargestMain {
public static void main(String[] args) {
int number = 0;
String numStr = "";
int []myArray = new int[10];
int count = 1;
int largest = 0;
boolean valid = false;
while(valid == true); { // Loop to check validity
for(int i = 0; i < myArray.length; i++) {
myArray[i] = i + 1;
numStr = JOptionPane.showInputDialog("Please enter number " + count++ + ":");
number = Integer.parseInt(numStr); // Converts string value to integer
if(number >= largest) {
largest = number;
}
// If-Else if statements checks if values entered are equal to 0-9
if(number >= 0 && number <= 9) {
valid = true;
}
else if ((!(number >= 0 && number <= 9))) {
valid = false;
}
if (valid == false) {
JOptionPane.showMessageDialog(null, "INVALID INPUT...Try Again!!!", "Results", JOptionPane.YES_OPTION);
continue;
}
}
JOptionPane.showMessageDialog(null, "The Largest Number Is: " + largest, "Results", JOptionPane.PLAIN_MESSAGE);
}
}
}
I could just end the loop here by adding return:
if (valid == false) {
JOptionPane.showMessageDialog(null, "INVALID INPUT...Try Again!!!", "Results", JOptionPane.YES_OPTION);
return;
}
I just really want to learn how to restart the loop from the beginning. I tried search different topics, but none helped me solve my problem. Thanks for the help in advance!
To restart a loop, you would use the continue keyword. continue will skip to the next loop iteration.
When using a while loop, it'll simply restart the loop, since the loop doesn't end til valid is true. When using a for loop, itll skip to the next iteration (so if you're currently on index 5 and use continue, it'll move onto index 6 instead of staying at 5).
For nested loops, you can label the loop to specify which loop the statement is for:
firstloop:
while(valid) {
secondloop:
while(true) {
continue firstloop;
}
}
Also, no need for == true when checking a boolean. It could be represented as
while(valid) {
}
As for checking for false, valid == false, you'd use
while(!valid) {
}
Since you're a beginner and trying to learn, I have done a review of your code and enclosed some comments that might help you. I have posted updated code below.
Declarations: You should declare a variable in the innermost closure that requires it. Except largest, all other can go inside the for.
Your array variable did not make sense to have. Since you're keeping track of the largest as you go and not finding it at the end.
Control: Your /loop to check validity/ needs to be strictly around the input part, not your whole program, so you can repeat just the input statements till you're satisfied.
public static void main(String[] args)
{
int largest = 0;
for(int i = 1; i <= 10; i++)
{
boolean valid = false;
while (!valid)
{
String numStr = JOptionPane.showInputDialog("Please enter number " + i + ":");
int number = Integer.parseInt(numStr); //Converts string value to integer
if (number >= 0 && number <= 9)
{
valid = true;
}
else
{
JOptionPane.showMessageDialog(null, "INVALID INPUT...Try Again!!!", "Results", JOptionPane.YES_OPTION);
}
}
if (number > largest)
{
largest = number;
}
}
JOptionPane.showMessageDialog(null, "The Largest Number Is: " + largest, "Results", JOptionPane.PLAIN_MESSAGE);
}
You can use a labeled continue:
firstloop:
while(valid){
secondloop:
for(int i=0; i<10; i++{
//something
if(something){
continue firstloop;
}
}
}
See the documentation for more details.
UPDATE: Also... there is no need for the condition in the else part of your if/else statement. Just doing a else{ valid=false } would be equivalent to what you're doing right now. Another option would be to simplify it even further and skip the if/else part alltogether and just have:
valid = number >= 0 && number <= 9
Write a recursive function, that is, a function that calls itself.
public static void DoSomething()
{
// optionally ask the user for input at this point before processing begins.
while(yourCondition)
{
// do your stuff.
}
// when execution reaches here the condition is no longer valid; start over.
if(conditionToStartOver)
DoSomething(); // start again
}
Your logic is almost right but you shouldn't be looping on valid in the outer loop. Remember, you want to stop the inner loop when an input is invalid. Normally the outer loop would give the user an option to exit the program.
So for example:
while(true) {
boolean valid = true;
for(...; ...; ...) {
...
if(number < 0 || 9 < number) {
valid = false;
break;
}
}
if(valid) {
// show largest input dialog
} else {
// show invalid input dialog
}
// optionally ask the user if they want to exit
// if so, break
}
I am have a program which prints off the fibonacci sequence up to a given input. The user puts in a number and it prints out the sequence up to that many numbers.
ex: input = 4 prints 1 1 2 3
I want to limit the program to only allowing an input 1-16. The way I have it now will print the sequence an then prints the error message? Any suggestions? Thank you
public class FibonacciGenerator
{
private int fibonacci = 1;
public FibonacciGenerator()
{
}
public int Fibonacci(int number)
{
if(number == 1 || number == 2)
{
return 1;
}
else if (number > 16)
{
System.out.println("Error must select 1-16");
}
else
{
int fib1=1, fib2=1;
for(int count= 3; count < 17 && count <= number; count++)
{
fibonacci = fib1 + fib2;
fib1 = fib2;
fib2 = fibonacci;
}
}
return fibonacci;
}
}
Here is my main method:
import java.util.Scanner;
public class FibonacciPrinter
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter an integer 1-16: ");
int input = in.nextInt();
FibonacciGenerator newNumber = new FibonacciGenerator();
System.out.println("Fibonacci sequence up to " + input + " places.");
for(int fibCount = 1; fibCount <= input; fibCount++)
{
int sequence = newNumber.Fibonacci(fibCount);
System.out.print(sequence);
}
}
}
As a recommendation don't make your methods or variables start with capital letter, capital letter is used by convention for Classes only.
Also, you should validate input variable before passing it to your method.
I mean:
if (input > 16 || input < 1) {
System.out.println("Enter a number between 1-16");
}
else {
for(int fibCount = 1; fibCount <= input; fibCount++)
{
int sequence = newNumber.Fibonacci(fibCount);
System.out.print(sequence);
}
}
In your Fibonacci function, your first line should be an if statement to see if the number is greater than 16. If it is, then you can throw an error.
Below is what it should be:
public int Fibonacci(int number) {
if (number > 16 || number < 1) throw new IllegalArgumentException("Error. Must select 1-16.");
// Rest of the code
}
In your Fibonacci function, for number not equal to 1 and 2. The return statement return fibonacci; will always be called. That's why the error message is printed with the sequence.
To avoid this, you can use #Frakcool method to validate variable input before passing it to Fibonacci function. Alternatively, you may use do-while loop to do this (force the user to retry).
do{
System.out.print("Enter an integer 1-16: ");
input = in.nextInt();
if (input<1 || input>16)
System.out.println("Error. Must select within 1-16.");
}while(input<1 || input>FibonacciGenerator.upper_limit);
Some other suggestion:
Make your methods and variables name start with a lower case letter
To avoid repeat calculation (for-loop in Fibonacci method), use integer array to store the fibonacci values and pass integer array instead of integer (for small input number such as 16). Another way is to set two more global variables to store the last and second last calculated values.
Make upper limit (and/or lower limit) as a global variable for better maintenance
public static int upper_limit = 16;
and get it in other class as
FibonacciGenerator.upper_limit
OK, I know I am missing something easy here, however I cannot find my mistake. The program runs fine, it just returns the wrong message. I am not calling it properly or something. I can remove the code form the display() method and put it in the check() method and it runs perfectly. Anyone want to help out a newbie who is stuck? I was unsure if the whole program needed to be displayed, if not I am sorry. A few times before I was told I did not put enough code in. I would also like any constructive feedback on the way I have written the code, as I do not want to pick up any bad habits.
public class Palindrome {
// Main Method
public static void main(String[] args) {
// Declare variables
int number;
// Call method
number = retrieveInput();
check(number);
display();
}// End main method
//*************************************************************************************
// Method to retrieve the input
public static int retrieveInput(){
//Declare variables
String number = null;
int numInput = 0;
boolean done = false;
// Prompt user for input and validate that input
while(!done){
try{
number = JOptionPane.showInputDialog("Enter 5 single digits");
numInput = Integer.parseInt(number);
if (numInput <10000 || numInput > 99999)
throw new NumberFormatException();
else
done = true;
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "Entry invalid. Please re-enter 5 single digits", "Error", JOptionPane.ERROR_MESSAGE);
}
}
return numInput;
}// End retrieveInput method
//*************************************************************************************
// Method to determine if input is a palindrome or not
public static boolean check(int number){
//Declare variables
int num1;
int num2;
int num4;
int num5;
boolean isPalindrome = false;
num1 = number / 10000;
num2 = number % 10000 / 1000;
num4 = number % 100/10;
num5 = number % 10;
// Checking to see if input is a palindrome
if (num1 == num5 && num2 == num4);
{
isPalindrome = true;
}
if (num1 != num5 && num2 != num4);
{
isPalindrome = false;
}
return isPalindrome;
}// End check method
//*************************************************************************************
// Method to display results
public static void display(){
// Declare variable
boolean isPalindrome = false;
// Display results
if (isPalindrome == true)
{
JOptionPane.showMessageDialog(null, "These 5 digits are a palindrome", "Results", JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null, "These 5 digits are NOT a palindrome", "Results", JOptionPane.INFORMATION_MESSAGE);
}
} // End display method
//*************************************************************************************
} // End class Palindrome
Change the last two lines of main to read
boolean isPalindrome = check(number);
display(isPalindrome);
Change the declaration of display to
public static void display(boolean isPalindrome){
and remove the line in display that says
boolean isPalindrome = false;
That way, the isPalindrome that display works with will be the same one that was evaluated in check.
Edit:
Also remove the semicolon at the end of
if (num1 != num5 && num2 != num4);
otherwise the block underneath it will run in every case, and set isPalindrome back to false. Alternatively, you could just remove this condition and the block below it entirely, because it actually doesn't do anything.
isPalindrome should be in your main method and take the value from your check method. Then pass it to display method. The way it is now the isPalindrome is always false, because it is just initialized to false in your display method and never changes.
Oh my god, you did something very silly in the check method. You say that isPalindrome is false, then display the value of isPalindrome without taking into account the fact that isPalindrome is calculated by a very different method and you have no way to get the value of it. What you can do is the same approach you used to get the number out of retrieveInput and put in check: function arguments. Here's a revised display method:
public static void display(boolean isPalindrome){
// Declare variable
boolean isPalindrome = false;
// Display results
if (isPalindrome == true)
{
JOptionPane.showMessageDialog(null, "These 5 digits are a palindrome", "Results", JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null, "These 5 digits are NOT a palindrome", "Results", JOptionPane.INFORMATION_MESSAGE);
}
}
Then, the main method needs to look like this:
public static void main(String[] args) {
// Declare variables
int number;
boolean isPalindrome
// Call method
number = retrieveInput();
isPalindrome = check(number);
display(isPalindrome);
}
the problem lies in that you aren't doing anything with the value you get back from check(). After you call it in main(), the value disappears since you don't assign it to any thing. Then in display() you create a new instance of isPalindrome and set it to false. this one has nothing to do with the one declared in check(). this one will always be false because you don't tell it otherwise. to fix it change your main() method's body to:
// Declare variables
int number;
boolean isPalindrome; //declare var
// Call method
number = retrieveInput();
isPalindrome = check(number); //assign it the value
display(isPalindrome); //pass this value on to display
and then your display to
public static void display(boolean isPalindrome){
// Declare variable
//don't need to decalre var as
//it is now a parameter to the function
//rest of method as before
}
This will allow your display to know whether or not the number is a palindrome or not.
Edit Also you are doing if's wrong!
after an if statement there is no semicolon!!
as a a result your' if's in check do absolutely nothing and will always return false!
also keep in mind what would happen with the number 12325. it is not a palindrome but it's first and last digits are the same whereas the second and forth are. neither of your if statements would evaluate as true if they were correct. the following is the fixed code:
import javax.swing.JOptionPane;
public class Palindrome {
// Main Method
public static void main(String[] args) {
// Declare variables
int number;
boolean isPalindrome; //add this var to store the value
// Call method
number = retrieveInput();
isPalindrome = check(number); //assign it so we know wheter it a palindrome or not
display(isPalindrome); //pass it to display() so it mknows wheter it is a palindrome or not
}// End main method
//*************************************************************************************
// Method to retrieve the input
public static int retrieveInput() {
//Declare variables
String number;
int numInput = 0;
boolean done = false;
// Prompt user for input and validate that input
while (!done) {
try {
number = JOptionPane.showInputDialog("Enter 5 single digits");
numInput = Integer.parseInt(number);
if (numInput < 10000 || numInput > 99999) { //don't throw an error, inefecient just show the error instead
JOptionPane.showMessageDialog(null, "Entry invalid. Please re-enter 5 single digits", "Error", JOptionPane.ERROR_MESSAGE);
} else {
done = true;
}
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Entry invalid. Please re-enter 5 single digits", "Error", JOptionPane.ERROR_MESSAGE);
}
}
return numInput;
}// End retrieveInput method
//*************************************************************************************
// Method to determine if input is a palindrome or not
public static boolean check(int number) {
//Declare variables
int num1,num2,num4,num5;
boolean isPalindrome;
num1 = number / 10000;
num2 = number % 10000 / 1000;
num4 = number % 100 / 10;
num5 = number % 10;
// Checking to see if input is a palindrome
if (num1 == num5 && num2 == num4){ //no semicolons!!! else the if does nothing
isPalindrome = true; // and it evaluateds whaat it was supposed to like normal code
}else{
isPalindrome = false;
}
return isPalindrome;
}// End check method
//*************************************************************************************
// Method to display results
public static void display(boolean isPalindrome) { // no variables to declare as it now a parameter
// Display results
if (isPalindrome == true) {
JOptionPane.showMessageDialog(null, "These 5 digits are a palindrome", "Results", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, "These 5 digits are NOT a palindrome", "Results", JOptionPane.INFORMATION_MESSAGE);
}
} // End display method
//*************************************************************************************
} // End class Palindrome
The program is designed for the user to enter a series of numbers until the user enters the sentinel which i set to the value of 0. After the user enters the sentinel the program is supposed to print the highest number and the second highest number in that list. The trouble I'm having is where I expect the second highest number to be it prints 0 instead.
Is there a more elegant way of solving this problem by using the ?: operator? Is it possible?
import acm.program.*;
public class LargestAndSecondLargest extends ConsoleProgram {
public void run() {
int a = 0;
int b = 0;
while (true) {
int value = readInt(" ?: ");
if (value == SENTINEL) break;
if (value > a) {
a = value;
}
else if (value > b) {
b = value;
}
}
println("the largest value is " + a);
println("the second largest number is" + b);
}
private static final int SENTINEL = 0;
}
There are two issues:
The second comparison is wrong.
When you encounter a new highest number, you need to shift the previous highest number into the second-highest slot. Otherwise the sequence 1, 2, 3 would produce 3 and 1 as the two highest numbers.
else if ( b > value )
The above else if condition should be: -
else if ( value > b )
Else, your b will never get changed, if you are entering only positive numbers, and hence the 2nd largest value will be 0.
Also see 2nd requirement in #NPE's answer that is necessarily required.
insert the values into an array. Sort the array then assign the top two values from the array into your output. if only one value is given depending on requirements set them both to the same value or one to 0.
Here my solution (that you can adapt with your superclass):
public class LargeAndSecondLargest {
public static void main(String[] args) {
new LargeAndSecondLargest().run("1 2 2");
}
public void run(String input) {
final int SENTINEL = 0;
int currVal;
Scanner scanner = new Scanner(input);
List<Integer> numbers = new ArrayList<>();
while (scanner.hasNextInt() && ((currVal = scanner.nextInt()) != SENTINEL)) {
numbers.add(currVal);
}
printFirstAndSecondLargest(numbers);
}
private void printFirstAndSecondLargest(List<Integer> numbers) {
Collections.sort(numbers, Collections.reverseOrder());
System.out.println("the largest value is " + numbers.get(0));
System.out.println("the second largest number is " + numbers.get(1));
}
}