I'm trying to create a recursive method that returns a value, and prints the value in my main method. I'm confused on how to return and print in main() a row of X asterisks (**..)
X being a integer on the commandline.
For example the commandline argument is 5.
It should output to: *****
My code so far:
public static void main(String[] commandlineArguments){
if(commandlineArguments.length == 0){
System.out.println("Please enter a least one commandline!");
}
else{
Integer number = new Integer(0); //initialize number
try{
Integer x = Integer.parseInt(commandlineArguments[0]);
}
catch(NumberFormatException exception){ //NumberFormatException
System.out.println(exception+" is not a integer!");
System.exit(1); //end program
}
Integer num1 = recursiveMethods.asterisks(number); //A (return address)
System.out.println(num1);
}
}
public static Integer asterisks(Integer number){
String asterisks1 = "*";
for(int i = 0; i < number; i++){
return i;
}
return number;
}
}
A recursive method have two characteristics:
It calls to itself to provide the solution
It has a base case that contains where the recursive call must stop.
Your asterisks method does not fulfill any of these. Since this looks like homework, I would only provide an explanation about how this method should be, the implementation will be yours:
Since your method needs to return asterisks, it would be better returning a String instead of an Integer. This String will contain all the *s needed.
Define a base case. This can be where number have a value of 1.
If number is greater than 1, then you should return an asterisk and the result of calling to asterisks method using the rest of asterisks the whole result needs.
The problem is here:
for(int i = 0; i < number; i++){
return i;
}
This loop will only run one time, and it will immediately return i = 0. You don't want that. Make it append a * to your asterisks1 variable each iteration, then after the loop is finished, return asterisks1 to the caller and print it.
Also, just FYI, this method is not recursive. A recursive method by definition calls itself at some point.
You probably want to call the asterisk function recursively, and return the built up String of asterisks, something like this:
public static void main(String[] commandlineArguments) {
if (commandlineArguments.length == 0) {
System.out.println("Please enter a least one commandline!");
} else {
Integer number = new Integer(0); // initialize number
try {
number = Integer.parseInt(commandlineArguments[0]);
} catch (NumberFormatException exception) { // NumberFormatException
System.out.println(exception + " is not a integer!");
System.exit(1); // end program
}
String asterisk = asterisks(number); // A (return address)
System.out.println(asterisk);
}
}
public static String asterisks(Integer number) {
if (number == 0) {
return "";
} else {
return "*" + asterisks(number - 1);
}
}
to do it recursively you must call itself in itself. for example :
public static void main(String[] commandlineArguments){
if(commandlineArguments.length == 0){
System.out.println("Please enter a least one commandline!");
}
else{
Integer number = new Integer(0); //initialize number
try{
Integer x = Integer.parseInt(commandlineArguments[0]);
}
catch(NumberFormatException exception){ //NumberFormatException
System.out.println(exception+" is not a integer!");
System.exit(1); //end program
}
recursiveMethods.asterisks(number); //A (return address)
}
}
public static void asterisks(Integer number) {
if(number == 0)
return;
else {
System.out.print("*");
asterisks(number - 1);
}
}
}
Can be done as,
public static String asterisks(int n){
return (n==1)?"*":asterisks(n-1)+"*";
}
Note : return Type is String
EDIT: For n <= 0 it prints nothing
public static String asterisks(int n){
return (n<=0)?"":asterisks(n-1)+"*";
}
Related
I don't know where am I going wrong. I want to count zeroes via recursion but I am not getting it:
public class countzeroes {
public static int countZerosRec(int input){
int count=0;
return countZerosRec(input,count);
}
private static int countZerosRec(int input ,int count){
if (input<0) {
return -1;
}
if(input==0) {
return 1;
}
int m = input%10;
input = input/10;
if(m==0){
count++;
}
countZerosRec(input,count);
return count;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
System.out.println(countZerosRec(n));
}
}
Put return count in if(input == 0) statement and instead of
countZerosRec(input, count); return count; put return countZerosRec(input, count);.
The correct method would be:
public class countzeroes {
private static int countZerosRec(int input){
if (input<0) {
return -1;
}
if (input==0) {
return 1;
}
if(input < 10) {
return 0;
}
int m = (input%10 == 0)? 1: 0;
input = input/10;
return m + countZerosRec(input);
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
System.out.println(countZerosRec(n));
}
}
Let me explain 2 problems in your code:
1- First of all, your second if statement (if(input == 0)) ruin everything. Consider 1200100 as an example. In the 6th round of recursion the input would be 1, and if you divide it on 10 the result is 0 (which is the input of next recursion round) and therefore all the answers would be 1.
2- Secondly, it would be nice if you don't change the input parameter in your code. because it's completely error-prone (In complicated codes, you can not trace the changes happen on a parameter and it makes debugging hard). So, I just removed the count parameter from the input.
And finally, It is better to name your classes in CamelCase form. (CountZeroes)
Change your method as below. Return count always
private static int countZerosRec(int input ,int count){
if (input <= 0) { // check if input is negative or zero
return count;
}
int m = input % 10;
input = input / 10;
if (m == 0) {
count++; // increment if current digit is zero
}
return countZerosRec(input,count);
}
public static int zeroCount(int num)
{
if(num == 0)
return 0;
if(num %10 ==0)
return 1 + zeroCount(num / 10);
else
return zeroCount(num/10);
}
this would work
You can use Streams:
System.out.println("11020304".chars().filter(c -> c == '0').count());
Result: 3
Your count logic is excellent.
in below line ... you are making logic mistake.. just fix it.
private static int countZerosRec(int input, int count) {
if (input < 0) {
return -1;
}
if (input == 0) {
return count;
//return 1; /// you need to change your code here, in last its getting zero as (num < 10 )/10 is 0
// its entering here everytime, and returning one.
// since its the base condition to exit the recursion.
// for special case of 0 (zero) count, handle your logic when it is //returned.
//...... rest of your code
}
Here's the code (number operations class is the second listed):
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// declare and instantiate ArrayList with generic type <NumberOperations>
ArrayList<NumberOperations> numOpsList
= new ArrayList<NumberOperations>();
// prompt user for set of numbers
System.out.println("Enter a list of positive integers separated "
+ "with a space followed by 0:");
// get first user input using in.nextInt()
int number = in.nextInt();
// add a while loop as described below:
// while the input is not equal to 0
// add a new NumberOperations object to numOpsList based on user
input
// get the next user input using in.nextInt()
while (number != 0) {
numOpsList.add(new NumberOperations(number));
number = in.nextInt();
}
int index = 0;
while (index < numOpsList.size()) {
NumberOperations num = numOpsList.get(index);
System.out.println("For: " + num);
// add print statement for odds under num
// add print statement for powers of 2 under num
index++;
}
public class NumberOperations {
// instance variables
private int number;
// constructor
/**
* #param numberIn is number
*/
public NumberOperations (int numberIn) {
number = numberIn;
}
// methods
/**
* #return value
*/
public int getValue()
{
return number;
}
public String oddsUnder()
{
String output = "";
int i = 0;
while (i < number) {
if(i % 2 != 0) {
output += i + "\t";
}
i++;
}
return output;
}
public String powersTwoUnder()
{
String output = "";
int powers = 1;
while (powers < number) {
output += powers + "\t";
powers = powers * 2;
}
return output;
}
public int isGreater (int compareNumber)
{
if (number > compareNumber)
{
return 1;
}
else if (number < compareNumber)
{
return -1;
}
else
{
return 0;
}
}
public String toString()
{
String output = "";
return number + "";
}
}
The error I'm getting is that the compiler can't find "NumberOperations" anywhere. Its probably a very rudimentary issue I have, but I'm lost.
Edit: I added the class for numberoperations in case it helps. I thought I did everything right as far as this goes though.
Enter a list of positive integers separated with a space followed by 0:
1 2 3 4 0
For: 1
For: 2
For: 3
For: 4
I decorated the main method with a class
import java.util.*;
public class NumberOperationsTest {
yes, import was left to the helping User, too.
Closed the class just before the class NumberOperations, which I freed from the public declaration, to have it compilable in a single file.
In a different file, the public keyword is fine.
On compilation, you have to tell the classpath, to look in the current directory:
javac -cp . NumberOperationsTest.java
At the moment I'm calling the method reader.nextInt() twice so it's only using the addNumber() method for every other value rather than each one.
How do I go about fixing this issue?
I've tried using a while loop containing (true) as well as the one printed below, both encounter the same issue.
I forgot to mention, I need the programme to print the sum of all integers entered. This is to be triggered by entering the value of -1. The -1 is meant to be excluded from the sum.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
NumberStatistics stats = new NumberStatistics();
Scanner reader = new Scanner (System.in);
System.out.println("Type numbers:");
while (reader.nextInt() != -1) {
stats.addNumber(reader.nextInt());
}
System.out.println("sum: " + stats.sum());
}
}
public class NumberStatistics {
private int amountOfNumbers;
private int sum;
public NumberStatistics() {
amountOfNumbers = 0;
sum = 0;
}
public void addNumber(int number) {
this.amountOfNumbers++;
this.sum += number;
}
public int amountOfNumbers() {
return this.amountOfNumbers;
}
public int sum() {
return this.sum;
}
public double average() {
if (this.sum() == 0) {
return 0;
}
else {
return (double) this.sum / this.amountOfNumbers;
}
}
}
You are calling twice nextInt(), hence reading two nubers one after the other.
You can do what you want like this:
int num;
while ((num = reader.nextInt()) != -1) {
stats.addNumber(num);
}
This makes use of the fact that assignment expressions (this: num = reader.nextInt()) not only assigns the value to num, but aslo evaluate to the value being assigned, so that we can compare it with -1.
The problem here is that the scanner will jump to the next token for each call of nexInt() that's why you get the following numbers, and skip the expected one.
So don't use nextInt() in your while condition, use hasNextInt() instead.
So your code would look like this:
int next;
while (reader.hasNextInt() && (next = reader.nextInt()) != -1){
stats.addNumber(next);
}
When you call nextInt(), the pointer in the scanner parse the int, then goes to the next element. So basically, you have :
pointer
|
|
12345 12346 12347
while (nextInt() ...) // pointer moves to next int
pointer
|
|
12345 12346 12347
stats.addNumber(reader.nextInt()); // Now the pointer is already at the next one
So you are reading them two by two. You can correct this by doing:
int a;
while ((a = reader.nextInt()) != -1)
stats.addNumber(a);
This way, the Reader#nextInt method is only called once.
I'm doing a program where user input five numbers and in the end the numbers are printed out which is working fine. What I can't get to work is a boolean function to check for duplicates. It should check for duplicates as the user write them in, so e.g. if number one is 5 and the second numbers is also 5, you should get an error until you write in a different number. Meaning if the user input a duplicate it should NOT be saved in the array. This is obviously an assignment, so I'm just asking for a hint or two.
This program is written based on pseudo-code given to me, and therefore I have to use a boolean to check for duplicates with the public boolean duplicate( int number ) class.
I've tried getting my head around it and tried something by myself, but obviously I'm doing a stupid mistake. E.g.:
if(int i != myNumbers[i])
checkDuplicates = false
else
checkDuplicates = true;
return checkDuplicates;
DuplicatesTest class:
public class DuplicatesTest {
public final static int AMOUNT = 5;
public static void main(String[] args) {
Duplicates d = new Duplicates(AMOUNT);
d.inputNumber();
d.duplicate(AMOUNT);
d.printInputNumbers();
}
}
Duplicates class:
public class Duplicates {
private int amount;
private int[] myNumbers;
private boolean checkDuplicates;
public Duplicates(int a) {
amount = a;
myNumbers = new int[amount];
}
public void inputNumber() {
for(int i = 0; i < amount; i++ ) {
int input = Integer.parseInt(JOptionPane.showInputDialog("Input 5 numbers"));
myNumbers[i] = input;
}
}
public boolean duplicate( int number ) {
<BOOLEAN TO CHECK FOR DUPLICATES, RETURN FALSE OR TRUE>
}
public void printInputNumbers() {
JTextArea output = new JTextArea();
output.setText("Your numbers are:" + "\n");
for(int i = 0; i < myNumbers.length; i++) {
if (i % 5 == 0) {
output.append("\n");
}
output.append(myNumbers[i] + "\t");
}
JOptionPane.showMessageDialog(null, output, "Numbers", JOptionPane.PLAIN_MESSAGE);
}
}
Sorry if the code tag is messy, I had some trouble with white fields in between and such. I'm new here.
Don't store the numbers in an array. Use a Set<Integer> instead. And then do a Set#contains() operation. It's O(1) operation which is actually far better than iterating over the array to search for duplicates.
Ok, if it's a compulsion to use an array, then you should modify your current approach, to return true as soon as you find a duplicate, instead of iterating over the array again. In your current approach, since you are setting the boolean variable to false in the else block, your method will return false if the last element of the array is not the same as what you are checking. So, just modify your approach to:
// loop over the array
if (number == myNumbers[i])
return true;
// outside the loop, if you reach, return false
return false;
Note that your current if statement will not compile. You are declaring an int variable there, which you can't do.
if (int i == myNumbers[i]) // this is not a valid Java code.
int nums[] = new int[5];
int count = 0;
public boolean duplicate(int number)
{
boolean isDup = false;
for (int i = 0; i <= count; i++)
{
if (number == nums[i])
{
isDup = true;
break;
}
}
if (!isDup)
{
count++;
nums[count] = number;
}
return isDup;
}
import java.util.Scanner;
public class Return {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
inputTest();
}
public static void inputTest(){
System.out.println("From Digit (9635)");
System.out.print("Enter a Digit: ");
int number = input.nextInt();
System.out.println(Digit(number));
}
public static int Digit(int number) {
if (number == 1) {
System.out.print("The 4th number in the argument is =\t");
return 5;
} else if (number == 2) {
System.out.print("The 3rd number in the argument is =\t");
return 3;
} else if (number == 3) {
System.out.print("The 2nd number in the argument is =\t");
return 6;
} else if (number == 4) {
System.out.print("The 1st number in the argument is =\t");
return 9;
} else {
System.out.print("Sorry! That's not part of the argument =\t");
**return 0;**
}
}
}
/* is it possible to use (string, int) in the same method to get a
return (string) and return (int)??
i want to that return 0(int) to become return none(String) */
You can't have two return values from the same method, but you can:
Return String.valueOf(int), or
Return a custom object that contains both a String and an int
You have 2 options:
1) Use a return object with 2 properties such as Apache Pair. See http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html
2) Pass in an object (e.g., a StringBuilder) and have that object store one of your return values (e.g., StringBuilder.append).
You can't do it. The method:
public static int Digit(int number){
...
}
has to return an integer as specified.
But you can change it to a String after the value is returned (i.e. in your inputTest method)
public static void inputTest(){
System.out.println("From Digit (9635)");
System.out.print("Enter a Digit: ");
int number = input.nextInt();
int digit = Digit(number);
if(digit!=0)
System.out.println(digit);
else
System.out.println("none");
}
If you are willing to compromise on the return type, you could return a HashMap of the values you require