Java function is not returning expected value - java

A bug in a program I'm writing as an assignment for my java.
Objective: program should take two parameters and find all the odd numbers between those parameters. Then it should return the sum of all those numbers.
Bug: When the parameters are negative or starting number is greater than the ending number, it should return -1. But my program is returning 0.
Maybe my program isn't updating the sum value inside the loop. But even so, as per return condition, my function should return -1, not the sum.
public class SumOddRange{
public static void main(String[] args){
System.out.println(sumOdd(10,5));
}
public static boolean isOdd(int number){
return (number<0)||(number%2==0)?false:true;
}
public static int sumOdd(int start, int end){
int sum = 0;
for(int i=start; i<=end; i++){
if(isOdd(i)){
sum+=i;
}
}
return (start<=0)&&(start>end)? -1: sum;
}
}

Put the input check as the first thing in your method and change the && to an || since you want to return if the first check fails or the second check fails, not only if both fail. And the isOdd can be inlined:
public static int sumOdd(int start, int end){
if (start <= 0 || start > end)
return -1;
int sum = 0;
for (int i = start; i <= end; i++) {
if (i % 2 != 0) { // or if (i % 2 == 1) {
sum += i;
}
}
return sum;
}

There is a logic error in your line return (start<=0)&&(start>end)? -1: sum;
You have to return -1 if start is <0 or start > end, so use "||" (logical Or) instead of "&&" (logical and):
return (start<=0)||(start>end)? -1: sum;
Please go through #luk2302's answer for a better solution.

Related

Recursive function that has an array of integers and it's size as parameters that will return true if the sum of the array elements is even?

How do I create a function that has an array of integers and the array's length as parameters that will return true if the sum of the array elements is even and false otherwise?
How would I do this without using any static variables?
I've tried making a code that will check if,
current is odd and previous is even will return false recursively, else will return true recursively, this idea is based on the mathematical axiom that only even plus odd is equal to odd, every other combination is even.
public static boolean q3(int[] arr, int index) {
if (index == 0) {
return arr[index] % 2 == 0;
}
if (arr[index] % 2 == 0) {//if current is even
if (!q3(arr, index - 1)) {//even plus odd = odd
return false;
} else
return true; //every other combo equal true
} else if (q3(arr, index - 1)) {//if current is odd
return true;
} else {
return false;
}
}
I wrote 2 versions, one with recursion, other with no recursion
import java.util.Arrays;
public class MyClass {
public static void main(String args[]) {
int[] arr={5, 3, 1};
System.out.println("sum of "+Arrays.toString(arr)+" is " + size_ispair_rec(arr, arr.length));
}
public static boolean size_ispair_rec(int[] arr, int size){
if(size-1 == 0){
return arr[size]%2==0;
}
return !((arr[size-1]%2 == 0) ^ size_ispair_rec(arr, size-1));
}
public static boolean size_ispair(int[] arr, int size){
int sum=0;
for(int i=0; i<size; ++i){
sum+=arr[i];
}
return sum%2 == 0 ? true : false;
}
}
Here is a recursive method that does the job. I've tried to keep the code readable.
The idea is that the only time you get an even number by addition is when
Both the numbers are even
Both the numbers are odd
At every recursive call, we check if adding the number to the previous calculated value makes it even or odd.
public static boolean isSumEven(int arr[], int length){
if(length == 0){
return true;
} else {
boolean sumPreviousElemsEven = isSumEven(arr, length - 1);
boolean currentElemEven = arr[length-1]%2 == 0 ? true : false;
if(sumPreviousElemsEven && currentElemEven || !sumPreviousElemsEven && !currentElemEven){
return true;
} else {
return false;
}
}
}

How to recursively count number of occurences in an array

I've got a task that gets an int value "n" and an Int Array as parameters and is supposed to return a boolean.
The method is supposed to determine, how many "n" are in the given Array. If the number is even the method should return true, else false. If the Array has the length 0, it should return "false" aswell.
What i managed to do is :
public static boolean evenNumberOf(int n, int[] arr) {
boolean result = false;
System.out.println("Starting count");
if (n < arr.length) {
if (arr[n] == n) {
result = true;
} else {
return evenNumberOf(n - 1, arr);
}
}
return result;
}
Im just really confused and i dont know what to do to be honest. I have really tried my best but the longer i work on this task the less i understand.
Any help is appreciated and thank you in advance! :)
Separate it into two methods:
The method you call initially
and a method that gets called recursively to count the number of ns in the array:
boolean evenNumberOf(int n, int[] arr) {
int count = countNs(n, arr, 0);
// Logic to choose what to return based on count and/or length of arr.
}
int countNs(int n, int[] arr, int i) {
// Check if arr[i] is equal to n.
// Make a recursive call to countNs for i := i + 1.
// Combine the check/recursive call result to return a value.
}
Try
//arr should not be empty, index and count >= 0
public static boolean evenNumberOf(int value, int index,int[]arr, int count) {
if(index >= arr.length) return count%2 == 0;
if(arr[index] == value ) {
count++;
}
return evenNumberOf(value, ++index, arr, count);
}
Usage example: System.out.println(evenNumberOf(2, 0, new int[]{2,0,3,7,6,11,1,2}, 0));
(You can add an helper method evenNumberOf(int value,int[]arr))
as Recursive Counting in an Array got closed as a duplicate I will answer it here:
Let's analyze what you did and why it's wrong
public static int countN(int n,int [] arr,int i, int count) {
if (arr[i] == n) {
System.out.println("MATCH");
count++;
return count;
}
Here you already return the count when you get a match. You shouldn't do that because if the first number is already the same it returns 1. all you need to do is increase the count here
else {
System.out.println("Moving on");
i = i + 1;
countN(n,arr,i, count);
}
Here you do the recursion. This is good. But this also needs to be done in the case that you do get a match. And it needs to return that value. But, also this only needs to be done when you are not at the end of the array yet
if (arr.length == i) {
evenNumberOf(n,arr);
}
this part doesn't make sense, because you call evenNumberOf with the exact same arguments as it started so it will result in an infinite loop. you should have returned the count here. also keep in mind that the last index of an array is length - 1
putting this together you can make:
public static int countN(int n,int [] arr,int i, int count) {
if (arr[i] == n) {
count++;
}
if (arr.length - 1 == i) {
return count;
}
return countN(n, arr, i + 1, count);
}

find if given pack of coins can make a given value - coin row problem

given array of coins (int) and an int n the function need to return true if there is atleast one solution to the coin-change problem.
meaning: for array of ints> 0: [c(0) ,c(1) ,c(2) ,c(3) ,...... ,c(k)]. check if there is a solution for
the eqauation: a(0)*c(0)+ a(1)*c(1)+.....+ a(k)*c(k)= n. //n is the money we need to change
given c(0),c(1),....,c(n) >0 and a(0),a(1),....,a(n) =>0 both integers.
so I managed to make this code: the problem is that its algorithmic efficiency sucks, and this should be running on high values, and big coins array, so I need a code that is able to do this quicker.
public static boolean change(int[] coins, int n) {
boolean ans = false;
//loop running in recursion till founds ans/ passing limit
for (int i = 0; i < coins.length & (!ans); i = i + 1) {
if (n % coins[i] == 0) {
return true;
}
if (n >= coins[i]) {
ans = change(coins, n - coins[i]);
}
}
return ans;
}//O(n*k^n) solution for false ans , very bad :(
for example: for coins = {2,4,8} and n= 4111; I should get false, but the program unable to run this.
btw I would prefer this function to use recursion, but any solution/ guidnes is good :)
this is an other try doing this better but still not running as wanted.
//trying to use binary search and using divisions instead of minus
public static int iscashable(int[] coins, int n, int min, int max)
{
int check=(max+min)/2;
if(check == coins.length-1 | check == 0)
return check;
if(n/coins[check] > n% coins[check])
{
return (iscashable(coins,n,check,max));
}
else
{
return check;
}
}
public static int canchange(int[] coins, int n, int count)
{
int x=0;
int check= iscashable(coins,n,0,coins.length-count);
if(n%coins[check]==0)
{
return 0;
}
if(check==0)
{
return n;
}
if(n/coins[check] > n% coins[check])
{
x= (n/coins[check]) - (n% coins[check]);
int k= n-(coins[check]*x);
return canchange(coins, k, count+1);
}
else
{
return canchange(coins,n-coins[check],count+1);
}
}
the problem is both about runtime and number of recursion calls (with big number given, every recursion layer is coins.length^(num of layers));
I really thank you for your help!

how to call a recursion call N number of times, given the number N?

I have an array of numbers: S= {4,5} and I want to check if this group creates the sum = 13.
In this case, yes: 4 + 4 + 5 = 13
Another example: s={4,5}, sum = 6 -> no
I wrote a recursive function to solve this:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);
}
But this function works only for 2 numbers in the array.
I need to write a recursive function that will deal with N numbers, like {4,9,3} or {3,2,1,7} etc.
I'm not sure how can I do this? How can I call a recursion N times, according to the length of the array? Or maybe I should change my algorithm completely?
Also - I'm not allowed to use loops.
return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);
You can generalize this with a loop like this:
for (int i = 0; i < s.length; ++i) {
if (isSumOf(s,n-s[i])) return true;
}
return false;
But, since you can't use loops, you can write the equivalent loop as another recursive method:
boolean withoutLoop(int [] s,int n, int i) {
if (i >= s.length) return false;
return isSumOf(s,n-s[i]) || recurse(s, n, i+1);
}
and then call it like so from your isSumOf method:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
return withoutLoop(s, n, 0); // Change here.
}
Or, if you want to write it more concisely:
return (n == 0) || (n < 0 && withoutLoop(s, n, 0));
Break the problem down:
Sum the numbers
Is the sum equal to 13?
Then think of a way to express summing an array as recursive task; e.g. Sum of elements 1 to N is element 1 + Sum of elements 2 to N.
Finally, turn that idea / expression into code.
For any recursion problem, use the template:
ResultType recursiveMethod(params) {
if( /* this is the simplest case */ ) {
return answer for the simplest case
} else {
partialResult = solve part of the problem
resultForRest = recursiveMethod(rest of problem)
}
}
Particularly for list processing, this becomes:
if(list is empty) {
return solution for an empty list
} else {
r = call self recursively for tail of list
return solution for head of list combined with r
}
(Where "head" is the first item, and "tail" is the rest. Tail may be empty.)
For your problem, the simplest case is an empty array:
if(s.length == 0) {
return n == 0;
}
For the else, the "part of the problem" is s[0] and the "rest of the problem" is s[1] onwards.
...
} else {
int head = s[0];
int[] tail = Arrays.copyOfRange(s,1,s.length-1);
return isSumOf(tail, n - head);
}
The code would be cleaner (and probably more efficient) if you used a List instead of an array directly, because you could then use List.subList() instead of copyOfRange().
You could also pass the whole array each time, along with an extra parameter indicating how much of the array has already been accounted for.
This should work:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
for (int x: s) {
if (isSumOf(s, n-x)) {
return true;
}
}
return false;
}
UPDATE:
Oh! no loop, only recursion, you will need an extra argument:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
return isSum2(s, n, 0);
}
public static boolean isSum2(int [] s,int n,int i)
{
if (i >= s.length)
return false;
return isSumOf(s,n-s[i]) || isSum2(s,n,i+1);
}

Logical Error in Java Program

I have created two methods that take in a number and should count from that number to 0 and print it out. One method incorporates a while loop, which works fine. The other method uses a for loop. But for some reason, I'm not getting the expected output in the method that uses a for loop. How come?
import java.util.*;
public class Methods
{
public static void main(String[] args)
{
int n = 10;
countdown(n);
countdown2(n);
}
public static int countdown(int num)
{
while(num >= 0)
{
System.out.println(num);
num--;
}
return 0;
}
public static int countdown2(int number)
{
for(int i = number; i <= number; i--)
{
System.out.println(number);
number--;
}
return 0;
}
}
Because of the way you've structured the for loop conditions:
i is initially set to the same value as number.
The loop continues while i is less than or equal to number.
i gets decremented every time round the loop.
Since i starts out as less than or equal to number, and gets smaller, you're not going to exit the loop any time soon. (This will only happen when i gets down to Integer.MIN_VALUE and then underflows to Integer.MAX_VALUE on the next iteration).
Changing the condition to i > 0 would be one way of resolving this; or you could initially set i to zero and increment it each time round the loop.
for(int i = number; i <= number; i--)
check loop your count is starting from number to number only.
you should count from number to 0.
for(int i = number; i >= 0; i--)
If ever a program is behaving in a way which does make sense, the first thing you should try is use the debugger to debug your code. This allows you to step through the program line by line and see what all the values are
If you have a while loop you can exchange it with a for loop like so (provide you don't have a continue statement)
for({initialise variable};{condition};{update expression}) {
{do something}
}
with
{initialise variable}
while({condition}) {
{do something}
{update expression}
}
or
{initialise variable}
while(true) {
if ({condition}) break;
{do something}
{update expression}
}
or
{initialise variable}
if({condition})
do {
{do something}
{update expression}
} while({condition});
public static int countdown2(int number)
{
for(;number>=0;)
{
System.out.println(number);
number--;
}
return 0;
}
That should work
public static int countdown2(int number)
{
for(int i = number; i >= 0; i--)
{
System.out.println(number);
number--;
}
return 0;
}
The condition in the second loop should be
i >= 0
public static int countdown2(int number)
{
for(int i = number; i >= 0; i--)
{
System.out.println(number);
number--;
}
return 0;
}

Categories