Recursion method in Java providing incorrect output - java

I am working on a program that will take five numbers from a user then using recursion will provide the user with the sum of those numbers. My program appeared to be working at first however in my testing I am finding that it is just taking the first number entered by the user and basically multiplying it by five rather than taking the different numbers and finding the sum. Where am I going wrong with this? Like I said I am not getting any errors however it is not taking the additional four numbers and calculating the sum of the five numbers. Any help is always appreciated thank you.
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;
public class sumRecusion2 {
static int i;
static int N = 5;
static int[] userNum= new int[N];
public static int sumUser(int newArray[]) {
int n = newArray.length;
if (n == 0)
return 0;
int ans = newArray[0]+sumUser(Arrays.copyOf(newArray, n-1));
return ans;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scnr = new Scanner(System.in);
try {
for(i = 0; i<=userNum.length-1; i++) {
System.out.println("Please enter a number: ");
userNum[i]= scnr.nextInt();
}}
catch(InputMismatchException ex) {
System.out.println("Please enter an integer without a decimal point!");
}
System.out.println("The sum of your numbers is: "+ sumUser(userNum));
}
}

Arrays.copyOf(newArray, n - 1) is just trimming of the last element from the array, meaning you are just summing the first element n times.
I would consider using Arrays.copyOfRange(newArray, 1, n) instead, which will make a copy of the array starting from the second element (trimming of the first element)
I, personally, might be tempted to pass in the array AND the index of the element to be summed, which would be more efficient then making n number of copies of the array...
static int i;
static int N = 5;
static int[] userNum = new int[N];
public static int sumUser(int newArray[], int index) {
if (index >= newArray.length) {
return 0;
}
int ans = newArray[index] + sumUser(newArray, index + 1);
return ans;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
userNum = new int[] {1, 2, 3, 4, 5};
System.out.println("The sum of your numbers is: " + sumUser(userNum, 0));
}
But, your requirements might differ

Related

Having trouble in printing the largest array number from the 20 randomly generated numbers

Ok so I been working on this assignment all day for the past 3 days but I haven't had any luck. I wasn't going to ask for help but I finally gave up. But there is also one more thing I need to implement to the code. This is what I gotta implement "Find the length of the longest continuous series of positive numbers in the array data. If the contents were: 4 5 0 2 . . . -1 88 78 66 -6. The length would be 3. For this problem, 0 is considered non-negative but not positive". Plus I have an issue where I can't print the largest int in the array of 20.
import java.util.Random;
import java.util.ArrayList;
public class arrayops {
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = nums.get(0);
for (Integer item : nums) {
if (item > greatestnum) {
greatestnum = item;
}
}
return greatestnum;
}
public static int randomData(ArrayList<Integer> nums) {
int[] array = new int [20];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = -100 + random.nextInt(201);
}
return -100 + random.nextInt(201);
}
public static void main(String[] args) {
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(1);
nums.add(4);
nums.add(13);
nums.add(43);
nums.add(-25);
nums.add(17);
nums.add(22);
nums.add(-37);
nums.add(29);
System.out.println("The Greatest Number from the hardcoded numbers " + findLargest(nums));
System.out.println("The Greatest number from the random numbers " + randomData(nums));
}
}
The findLargest method:
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = 0;
int greatestLen = 0;
for (Integer item : nums) {
if (item > 0) {
greatestLen++ ;
if(greatestLen > greatestnum)
greatestnum = greatestLen;
}
else
greatestLen = 0;
}
return greatestnum;
}
Logic used:
Keep the length of the longest chain encountered, and the length of current chain, in two separate variables (greatestnum and greatestLen respectively)
Increment greatestLen every time a positive number is encountered. If the number if less than or equal to zero, reset this count.
If the length of current chain is greater than the previous longest chain, sent the longest chain size to current chain size.
The problem is you created a list with random numbers but never put that list into the findLargest method. You also never created a method to find the consecutive positive numbers. If you didn't know how to go about coding it, I recommend drawing out an algorithm on paper.
Largest value in ArrayList...
public static int findL(ArrayList<Integer> nums)
{
int top = nums.get(0);
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i)>top)
{
top = nums.get(i);
}
}
return top;
}
Largest number of consecutive positives...
public static int positiveString(ArrayList<Integer> nums)
{
int longest = 0;
int count = 0;
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i) > 0)
{
count++;
}
else
{
if(longest<count)
{
longest = count;
}
count = 0;
}
}
return longest;
}
If you want to arrange the numbers into order you can simply use java.util.TreeSet. Then use the method last() to get the largest number.
public static int findLargest(ArrayList<Integer> nums) {
return new TreeSet<Integer>(nums).last();
}

Find Lowest, Highest, Median and Average Score using findKth

For this program, my goal is to...
Find the Highest, Lowest, Median and Average Score by using findKth
The user must input the numbers (Enter -1 to stop scanner) and they do not know how many there are and if they are sorted
However, I am seeing some issue with trying to do this.
The findKth method I am provided only takes in an int[]arr, and I cannot find a way to initialize an array to the specific size need for this project.
Could someone suggest a way to to do this?
Below are my test methods and my findKth
import java.util.*;
public class Statistics
{
public static void main(String[]args)
{
System.out.print("Enter Scores, -1 to end: ");
Scanner keyboard= new Scanner(System.in);
String numbers = null;
while(keyboard.nextInt()!=-1)
{
numbers= keyboard.next();
}
String[] parts = numbers.split(" ");
int[] n1 = new int[parts.length];
for(int n = 0; n < parts.length; n++)
{
n1[n] = Integer.parseInt(parts[n]);
}
int highest= n1.length-1;
int lowest=0;
int median= n1.length/2;
QuickSort.findKth(n1, highest);
System.out.println("High: "+n1[highest]);
QuickSort.findKth(n1, lowest);
System.out.println("Low: "+n1[lowest]);
QuickSort.findKth(n1, median);
System.out.println("Median: "+n1[median]);
}
}
public static void findKth(int[] arr, int k)
{
findKth(arr, 0, arr.length, k);
}
//Pre: arr[first]..arr[last-1] contain integers
// k must be in [first..last-1]
//Post: The elements in arr has been rearranged in such a way that arr[k] now contains the kth
// largest element
public static void findKth(int[] arr, int first, int last, int k)
{
int pivotLoc = rearrange(arr, first, last);
if (pivotLoc==k) return;
else if (pivotLoc>k) findKth(arr, first, pivotLoc, k);
else findKth (arr, pivotLoc +1, last, k);
}
I've tried different methods such as trying to parse the string for the numbers however I cannot do this as i cannot find a way to properly stop the scanner when the user inputs -1.
Also i have tried using ArrayList, but findKth with ONLY take an int[]arr. So this will not work.
Suggestions? I am stumped.
Use a List to collect the input:
List<Integer> input = new ArrayList<>();
input.add(n); // add each number
Then to convert to an array after all input:
int[] array = input.stream().mapToInt(Integer::intValue).toArray();
Your input loop is buggy. Although out of scope of the question, try a simpler loop, for example:
while (true) {
int n = keyboard.nextInt();
if (n == -1)
break;
input.add(n);
}

Java ArrayIndexOutOfBoundsException palindromic primes

I've been working on this code for class that needs to find the users desired number of palindromic prime numbers. Everything works fine when I have the while(primeCounter < desiredNumPrimes) except that it outputs one less than the desired number of prime numbers. I attempt to correct this by having the while statement be "<=" instead, but then I get an Array Index Out Of Bounds Exception. As you can see, I even check to make sure that the index of the array is not less that the index I am attempting to use in the if statement
Any help is appreciated.
import java.util.Scanner;
public class PalPrimes
{
public static void main(String [] args){
Scanner scan = new Scanner(System.in);
int primeCounter=1, numberToCheck=2; //start checking at 2 because primes >1
System.out.println("Please enter the desired number of palindromic primes");
int desiredNumPrimes = scan.nextInt();
int[] palPrimes = new int[desiredNumPrimes-1];
System.out.print(palPrimes.length);
//find palindromic primes
while(primeCounter<desiredNumPrimes){
if(isPrime(numberToCheck)==true && isPalindrome(numberToCheck)==true){
palPrimes[primeCounter-1]= numberToCheck;
numberToCheck++;
primeCounter++;
}
else{
numberToCheck++;
}
}
//display palindromic primes
if(primeCounter==desiredNumPrimes){
for(int i = 0; i<palPrimes.length; i++){
if(i%10==0){
System.out.println();
}
System.out.print(palPrimes[i] + " ");
}
}
}
//Check if number is a prime
public static boolean isPrime(int num){
if(num == 2){
return true;
}
for( int divisor = 2; divisor <= num/2; divisor++){
if (num % divisor ==0){
return false;
}
}
return true;
}
//reverse number to begin testing if palindrome
public static int reverse(int num){
int testNum = 0;
while(num !=0){
int lastDigit = num%10;
testNum = testNum*10+lastDigit;
num = num/10;
}
return testNum;
}
//Check if number is a palindrome
public static boolean isPalindrome( int num){
return num == reverse(num);
}
}
The issues are with initializations. The below 3 changes will resolve the issue. You are getting arrayindexoutofbounds since you are trying to change only the initialization but not the assignment
int primeCounter with 0
int[] palPrimes = new int[desiredNumPrimes];
palPrimes[primeCounter]= numberToCheck;
Start the prime counter at 0 as you haven't found any primes yet.
int primeCounter=0, numberToCheck=2;
You're making the size of palPrimes 1 less than the desired number of primes, so it will never be able to contain the desired number of primes. Instead, make it
int[] palPrimes = new int[desiredNumPrimes];
Then, you check for palPrimes[primeCounter-1] = numberToCheck;
Seeing as we started the counter at 0, this should be changed to:
palPrimes[primeCounter] = numberToCheck;
And the program should work.

How can I prevent the overlapping random numbers

How would i prevent duplicating numbers from random numbers.
I need to generate 5 numbers between 1 and 9 that are each different.
I would often get same numbers like 23334, how can i prevent that?
Any help would be great!
int num2 = (int) Math.round((Math.random()*9) +1);
int num1 = (int) Math.round((Math.random()*9) +1);
int num5 = (int) Math.round((Math.random()*9) +1);
int num3 = (int) Math.round((Math.random()*9) +1);
int num4 = (int) Math.round((Math.random()*9) +1);
One option is to use shuffle algorithm (e.g. Fisher-Yates shuffle ) to generate random sequence from 1 to 9, then take first 5 numbers of the sequence
Further explanation on StackOverflow: https://stackoverflow.com/a/196065/950427
Set<Integer> set=new HashSet<>();
while (set.size()<5) {
set.add( Math.round((Math.random()*9) +1));
}
After the set is filled you have 5 unique random numbers.
UPDATE: just to illustrate Jared Burrows' comment
Create a List includes the numbers that you want (1 to 9).
Generate random number from 0 to (size of the list minus 1).
Remove one element by index from the above generated random number. And add the removed element to a array which to be returned as a results
public static void main(String[] args) {
int []answers= returnRandomNonRepeatingNumbers(5,0,9);
for(int answer: answers) {
System.out.println(answer);
}
}
public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) {
List<Integer> pool=new ArrayList<Integer>();
for(int i=poolStart;i<=poolEnd;i++) {
pool.add(i);
}
int []answers=new int[sizeYouWant];
for(int i=0;i<sizeYouWant;i++) {
//random index to be pick and remove from pool
int randomIndex = (int) Math.round((Math.random()*(pool.size()-1)));
answers[i]=pool.remove(randomIndex);
}
return answers;
}
If the number of possible random values is small, you want to use shuffle.
List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
Collections.shuffle(values);
values = values.subList(0, 5);
If the number of possible random values is large, you want to test adding them to a Set (or the original list if small enough)
Set<Integer> valueSet = new HashSet<>();
Random rand = new Random();
while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1);
List<Integer> values = new ArrayList<>(valueSet);
Collections.shuffle(values, rand);
Note: you need to shuffle the set as it doesn't preserve order. e.g. the numbers 1,2,3 will always come out in that order with HashSet, not 3,2,1.
Floyd's subset selection algorithm is designed to do exactly what you want, and is extremely efficient even for large sets. Selecting m items from a set of n is O(m) average running time, independent of n. Here's a Java implementation.
/*
* Floyd's algorithm to chose a random subset of m integers
* from a set of n, zero-based.
*/
public static HashSet<Integer> generateMfromN(int m, int n) {
HashSet<Integer> s = new HashSet<Integer>();
for (int j = n-m; j < n; ++j) {
if(! s.add((int)((j+1) * Math.random()))) {
s.add(j);
}
}
return s;
}
One possible approach to this problem can be divide & conquer. Step of following describes the approach:
Say m is the minimum & n is the maximum, within what i wanna get x number of randoms
Choose a random p between m & n. Save it to an array of answer. decrease x by 1 as we get one answer to our problem.
Now take a q a random number between m & p-1, another r a random number between p+1 & n. Fill up the answer array with q & r decrease x 1 for q and another 1 for the r.
Now carry on this process recursively, until the lower bound (m) & higher bound (n) becomes equal or x becomes 0.
Benefit: benefit of this approach is that, in worst case, it's runtime will be O(x), where x is the number of random number required. The best case scenarion is also o(x), as i have to find at least n number of random. These two comprise average case to θ(x) complexity.
import java.util.Random;
class GenerateDistinctRandom{
static int alreadyPut = 0;
static Random rand = new Random();
public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax)
{
int randomNumbers[] = new int[howMany];
GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany);
return randomNumbers;
}
private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize)
{
if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize)
{
return ;
}
int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin;
storage[GenerateDistinctRandom.alreadyPut] = randomNumber;
GenerateDistinctRandom.alreadyPut++;
//calling the left side of the recursion
recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize);
recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize);
}
public static void main(String []args){
int howMany = 5;
int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9);
for(int i = 0;i < howMany;i++)
{
System.out.println(distinctNumber[i]);
}
}
}
I suppose you would need to store the ones that have been generated into an array and compare the new random number to the list to ensure it is unique.
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int[] numbers = new int[5];
int tempNumber = 0;
for(int numberCounter = 0; numberCounter < numbers.length;)
{
tempNumber = (int) Math.round((Math.random()*9) +1);
if(!contains(numbers, tempNumber)){
numbers[numberCounter++] = tempNumber;
}
}
}
public static boolean contains(final int[] numbersArray, final int tempNumber) {
for (final int numberFromArray : numbersArray) {
if (numberFromArray == tempNumber) {
return true;
}
}
return false;
}
I notice you did not use an array in your example, so in case you do not know how to use them yet, you could also make 5 variables.
int randomNumber = 0;
int firstNumber = Math.round((Math.random()*9) +1);
int secondNumber = 0;
while(secondNumber == 0){
randomNumber = Math.round((Math.random()*9) +1)l
if(randomNumber != firstNumber){
secondNumber = randomNumber;
}
}
And you could continue making while statements like that. But if you are supposed to know about arrays, you should definitely be using one to store the numbers.
How about this?
package com.se;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TestRandom {
List<Integer> comp = new ArrayList<>();
int listSize = 20;
public void doTask() {
Random ran = new Random();
int i = 0;
while(i < listSize){
int randomNumber = ran.nextInt(80) + 1;
if(!comp.contains(randomNumber)){
comp.add(randomNumber);
i++;
}
}
for(Integer num : comp){
System.out.println(num);
}
}
public static void main(String[] args) {
TestRandom testRandom = new TestRandom();
testRandom.doTask();
}
}

Summing two arrays by element, issue with carrying the 1

So I've gotten these two arrays to add properly when there is no need to carry anything. so a[0,1,1] + b[0,1,1] will give me c[0,0,2,2], but if I similarly do a[0,9,9] + b[0,9,9] I only get c[0, 0, 8, 8]. The loop in method addBigInts doesn't seem to work the way I thought it would. Any thoughts are appreciated.
import java.util.*;
public class AddBigInts {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
//init firstNum array
int[] firstNum = new int[getDigit()];
System.out.println("First number:");
//gets input to pop array
firstNum = getInt(firstNum);
//second array is same length
int[] secondNum = new int[firstNum.length];
System.out.println("Second number:");
//pop second array
secondNum = getInt(secondNum);
System.out.println(Arrays.toString(firstNum));
System.out.println(Arrays.toString(secondNum));
addBigInts(firstNum, secondNum);
}
//creates array that is one place bigger than entered #
public static int getDigit (){
Scanner console = new Scanner(System.in);
System.out.print("How many digits? ");
int arraySize = console.nextInt();
return arraySize + 1;
}
//populates array
public static int[] getInt (int[] num){
Scanner console = new Scanner(System.in);
for (int i=num.length-1; i>0; i--){
System.out.print("Digit " + i + ": ");
num[i] = console.nextInt();
}
return num;
}
//adds both arrays by index into the sum array
public static int[] addBigInts (int[]numArray1, int[] numArray2){
int count = Math.max(numArray1.length, numArray2.length);
int[] sum = new int[count+1];
//starting at numArray1 & 2 index, sums ints
for (int i=count-1; i>=0; i--){
//sum has to be +1 for numArray1 & 2 indexes
sum[i+1] = numArray1[i] + numArray2[i];
if (sum[i+1]>9){
//this line below doesn't seem to execute
sum[i]++;
sum[i+1] = sum[i+1] - 10;
}
else;
}
System.out.println(Arrays.toString(sum));
return sum;
}
}
You have:
sum[i+1] = numArray1[i] + numArray2[i];
You need:
sum[i+1] += numArray1[i] + numArray2[i];
By assigning instead of adding you are overwriting the carried 1 from the previous digit.
In your add bigints function, try change store the addition into a temp variable and use that in the if statement
int temp = numArray1[i] + numArray2[i]
if( temp > 9)

Categories