Numbers Divisible by 3 recursion - java

I am writting a program that takes input using a series of numbers. Using recursion and Arrays I am trying to add all the numbers entered that are divisible by 3 and add them together. Ex. 3 4 5 6
Output should be 9. My current output keeps giving me 3 as the output for my entries. Any help or suggestions?
import java.io.*;
import java.text.*;
public class Assignment9 {
public static void main (String args[]) throws IOException{
int i = 0;
int [] nums;
nums = new int [100];
InputStreamReader inRead = new InputStreamReader(System.in);
BufferedReader buffRead = new BufferedReader(inRead);
String line = buffRead.readLine();
try {
while (line.equals("0") == false && i<100) {
i++;
line = buffRead.readLine();
nums[i]=(int) Double.parseDouble(line);
}
} catch(IOException e) {
System.out.println("Array index out of bound");
}
int endIndex = computeSumDivisibleBy3(nums, 0, nums.length-1);
System.out.print ("The minimum number is " + min + ('\n'));
System.out.print ("The sum of the numbers divisible by 3 is " + endIndex + ('\n'));
}
}
public static int computeSumDivisibleBy3(int [] numbers, int startIndex, int endIndex) {
if(startIndex == endIndex) {
if(numbers[endIndex] %3 == 0){
return (int) numbers[endIndex];
} else {
return 0;
}
} else {
if(numbers[endIndex] %3 == 0) {
return (int) (computeSumDivisibleBy3(numbers, startIndex, endIndex - 1) + numbers
}
else {
return computeSumDivisibleBy3(numbers, startIndex, endIndex - 1);
}
}
}

Ok a few things here:
1) A number n is divisible by three if: n%3 == 0 not n%3 == 1
2) When you check to see if a number is divisible by 3, you are checking if the INDEX is divisible by 3, not the actually number in the array (use numbers[endIndex])
Sort those two things out and it should work. This seems like homework, so I'm wary to just give you the correct code rather than letting you work through it and understand it.
Once you get it working, I have two recommendations:
1) You should use an int[] instead of double[] for the array. Any number that isn't an integer won't cleanly divide by 3. When you are reading the file and adding to the array of numbers, use n%1==0 in an if statement to check if the number read is in fact an integer and should be added to your array. This will reduce the amount of recursive calls as the array will be potentially shorter assuming that you were able to dispose of some non integer values.
2) You can make a recursive method with just two parameters, the array of ints and one index. Probably not necessary, but saves you the headache of worrying about passing indices. HINT: startIndex never gets changed, your base case can be improved by knowing the length of the array.
Please feel free to ask me more questions in the comments if you want clarification/more hints.

...
String line = buffRead.readLine();
try {
while (line.equals("0") == false && i < 100) {
nums[i] = Double.parseDouble(line);
i++;
line = buffRead.readLine();
}
} catch (IOException e) {
System.out.println("Array index out of bound");
}
int sum = computeSumDivisibleBy3(nums);
System.out.print("The sum of the numbers divisible by 3 is " + sum + ('\n'));
.....
public static int computeSumDivisibleBy3(double[] numbers) {
return _computeSumDivisibleBy3(numbers, 0);
}
private static int _computeSumDivisibleBy3(double[] numbers, int currentIndex ) {
int sum = 0;
if (currentIndex != numbers.length) {
int currentNumber = (int)numbers[currentIndex];
sum = (currentNumber % 3) == 0 ? currentNumber : 0;
sum += _computeSumDivisibleBy3(numbers, ++currentIndex );
}
return sum;
}

Related

Java method to check if a given number is symmetric

iv made a method to check if a given number is symmetric or not.
-the method is based on the idea that the given number is an array .
-i gave the methood 4 deifferent parameters- numberLength , middle , point1,point2(both pointing at a certain digit in the number(as an array))
-although wrote the code correctly , and it works when im initializing a specific array ,
i dont know how to use the method for a given number .
How can i set this Method - with parameter (int number) , so i can chek on the given number.
Thank you A lot
update** i added the code :
public boolean isSymmetric(int num){
int digits;
int[] number;
number = new int[num];
int length = number.length;
int mid;
if(length%2 == 0) //
{
mid = length/2;
}else {
mid = length/2+1;
}
int pointer1 =0;
int pointer2 = mid;
while(pointer1<mid && pointer2 < length)
{
if(number[pointer1] == number[pointer2])
{
pointer1=pointer1+1;
pointer2=pointer2+1;
}
else
System.out.println("number is not symmetric");
return false;
}
System.out.println("number is symmetric");
return true;
}
The easiest way to check if number symmetric or not is to map it to String::class, just like this:
// Your input number
Integer maybeSymmetricNumber = 12321;
String str = String.valueOf(maybeSymmetricNumber), reverseStr = "";
int strLength = str.length();
for (int i = (strLength - 1); i >=0; --i) {
reverseStr = reverseStr + str.charAt(i);
}
if (str.toLowerCase().equals(reverseStr.toLowerCase())) {
System.out.println(str + " is a symmetric number.");
}
else {
System.out.println(str + " is not a symmetric number.");
}
First, here is a method to convert your number to an array of ints.
it works by using the Math.log10 to compute the exponent of 10 for that number.
e.g. Math.log10(1234) = 3.xxx. So convert to an int and add 1 to get 4.
e.g. Math.log10(1000) = 3 so do the same thing.
then use that number to create an array of proper size.
and use the remainder(%) and division(/) operators to populate it.
then return the array.
public static int[] toArray(int number) {
number = Math.abs(number);
int[] arr = new int[(int) Math.log10(number)+1];
int i = 0;
while (number > 0) {
arr[i++] = number%10;
number/=10;
}
return arr;
}
Unfortunately, your method doesn't work properly as it always returns false. This is because of missing {} around the following.
else
System.out.println("number is not symmetric");
return false;
But it still doesn't process all values properly. Try 1234321 and 112211. They both return false but are symmetric. This is because pointer1 starts at 0 and pointer2 starts at mid and they are both incremented by 1.
I suggest you start pointer2 at length-1, going from outside in toward mid. This should then solve the issue (with a little debugging of course).

Why Does my Palindrome Code not work? My reverse variable does what it is supposed to but I dont get true even when it is printing out a palindrome

public class NumberPalindrome {
public static boolean isPalindrome(int number) {
int reverse = 0;
if (number<0){
number=number* -1;
}
while (number > 0) {
int lastDig = number % 10;
reverse = lastDig + reverse;
if (number<10) {break;}
reverse = reverse * 10 ;
number/=10;
}
if (number==reverse) {
return true;
}
return false;
}
}
why does my code not return true when I enter a palindrome number? I tried using it to print out the reverse value and it does it quite well, but just does not seem to get the boolean value straight though.
The problem was modifying the number variable, but then comparing it with the new generated reverse variable as if it was never edited.
Also, you were adding the last digit to the reverse variable before multiplying it by ten.
See the following code in Java:
public static boolean isPalindrome(int number) {
int reverse = 0;
if(number < 0) {
number *= -1;
}
int initialNumber = number;
while(number > 0) {
int lastDigit = number % 10;
reverse = (reverse * 10) + lastDigit;
if(number < 10) {
break;
}
number /= 10;
}
return initialNumber == reverse;
}
There are a few problems here. You need to save the original number for comparison with the the reversed number. The break statement confuses the logic.
To figure this out, I added some print statements to trace the progress. Adding print statements isn't elegant, but it is very useful.
Here is my version, with comments indicating what I changed.
public static boolean isPalindrome (int original)
{
// Need to save the original number for comparison
int number = original;
int reverse = 0;
if (number < 0)
{
number = number * -1;
}
while (number > 0)
{
int lastDig = number % 10;
// Update and shift reverse in one step
reverse = lastDig + reverse * 10;
number /= 10;
// Don't need extra break to terminate the loop
System.out.printf ("Check %d ; Reverse %d%n", number, reverse);
}
System.out.printf ("Final %d ; Reverse %d%n", number, reverse);
// Compare to original and return boolean value directly
return (original == reverse);
}

How do I use a recursion for sum of squares from user input?

Let's say for the user input 1, I can easily find the square of it. (A single digit input)
How do I use a recursive method to find the sum of squares (input with more than one number) e.g. 12345 should give 1*1 + 2*2 + 3*3 + 4*4 + 5*5 = 55? For the base case, it is correct to as num == 1 right? And from there, how do I compute the subsequent number behind 1?
public static int squareSum(int num) {
if (num == 1) {
return num*num;
} else {
return 0;
}
}
You have to think about the small steps first. It is all about extracting the digits and the calculating the squares.
public static int squareSum(int num) {
if (num == 0) return 0;
return (num%10)*(num%10) + squareSum(num/10);
}
For 12345 :-
f(12345)
f(1234)+5*5
f(123)+4*4+5*5
f(12)+3*3+4*4+5*5
f(1)+2*2+3*3+4*4+5*5
f(0)+1*1+2*2+3*3+4*4+5*5
The problem is, that you can't get the number at position x easily. The fact that 12345 consists of the numbers 1, 2, ... is only obvious in the decimal system. We will therefore store our number as a String, take each character and parse it to an integer. Then we square the number and add them
int i sum = 0;
String iAsString = i;
for (int i = 0; i < iAsString.length; i++) {
int currentNumber = Character.getNumericValue(iAsString.charAt(i));
sum += currentNumber * currentNumber;
}

Error in program when parsing negative integers into an array

I am having a strange issue with one of my assignments. I am attempting to take integers from user input and store them in an array. After that, four recursive methods will be run on them to find different characteristics of those numbers. However, whenever I attempt to run the program with a negative integer in any of the indexes the program stops responding.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Assignment9 {
public static void main(String[] args) throws IOException {
int index = 0;
int[] numbers;
numbers = new int[100];
InputStreamReader inRead = new InputStreamReader(System.in);
BufferedReader buffRead = new BufferedReader(inRead);
String line = buffRead.readLine();
try {
while (!line.equals("0") && index < 100) {
numbers[index] = Integer.parseInt(line);
index++;
line = buffRead.readLine();
}
} catch (IOException exception) {
System.out.println("Array index out of bound");
}
` int min = findMin(numbers, 0, numbers.length - 1);
int sumAtEven = computeSumAtEvenIndexes(numbers, 0, numbers.length - 1);
int divByThree = countDivisibleBy3(numbers, 0, numbers.length - 1);
System.out.println("The minimum number is " + min);
System.out.println("The sum of numbers at even indexes is " + sumAtEven);
System.out.println("The count of numbers that are divisible by 3 is " + divByThree);
System.out.println("The maximum number among numbers that are less than the first number is " + maxLessThanFirst);
}
public static int findMin(int[] numbers, int startIndex, int endIndex) {
if (startIndex == endIndex) {
return numbers[startIndex];
} else if (findMin(numbers, startIndex, endIndex - 1) < numbers[endIndex]) {
return findMin(numbers, startIndex, endIndex - 1);
} else {
return numbers[endIndex];
}
}
public static int computeSumAtEvenIndexes(int[] numbers, int startIndex, int endIndex) {
if (startIndex == endIndex) {
if (startIndex % 2 == 0) {
return numbers[startIndex];
} else return 0;
} else {
if (endIndex % 2 == 0) {
return computeSumAtEvenIndexes(numbers, startIndex, endIndex - 1) + numbers[endIndex];
} else {
return computeSumAtEvenIndexes(numbers, startIndex, endIndex - 1);
}
}
}
public static int countDivisibleBy3(int[] numbers, int startIndex, int endIndex) {
if (startIndex == endIndex) {
if (numbers[startIndex] % 3 == 0) {
return 1;
} else {
return 0;
}
} else {
if (numbers[endIndex] == 0) {
return countDivisibleBy3(numbers, startIndex, endIndex - 1);
}
if (numbers[endIndex] % 3 == 0) {
return countDivisibleBy3(numbers, startIndex, endIndex - 1) + 1;
} else {
return countDivisibleBy3(numbers, startIndex, endIndex - 1);
}
}
}
}
This is the only relevant section of code that is necessary to understand the problem, I believe. If additional code is needed just ask. Thank you!
Replace your findMin method. Pass the array and zero for the index;
public static int findMin(int[] numbers, int index) {
if (index == numbers.length - 1)
{
return numbers[index];
}
else
{
return Math.min(numbers[index], findMin(numbers, index + 1));
}
}
Your findMin method is doubly recursive:
public static int findMin(int[] numbers, int startIndex, int endIndex) {
if (startIndex == endIndex) {
return numbers[startIndex];
// in the next line, we recurse looking for the minimum
} else if (findMin(numbers, startIndex, endIndex - 1) < numbers[endIndex]) {
// we've found the minimum, but now we must recurse again to get it!
return findMin(numbers, startIndex, endIndex - 1);
} else {
return numbers[endIndex];
}
}
This transforms what should be a linear algorithm into an exponential one. If you log each time findMin is entered, you will find it increases rapidly with the size of the array. Experimentation shows that it is called 2^(x-1) + 2^(x-2) - 1 times, where x is the length of the array.
So if you had an array of size 10, it would be called 767 times. For an array of size 20, it would be called 786,431 times. Size 30, 25,165,823 times. Size 100 yields:
950,737,950,171,172,051,122,527,404,031 calls (950 octillion, 9.5 x 10^29).
Your program will not crash with a StackOverflowError because at no time does the stack depth exceed roughly the length of the array (plus one for the main), but it will take longer than the lifespan of the universe to run.
Changing findMin to this:
public static int findMin(int[] numbers, int startIndex, int endIndex) {
if (startIndex == endIndex) {
return numbers[startIndex];
}
// there's no need for an else since the if ended with a return
int r = findMin(numbers, startIndex, endIndex - 1); // only recurse once
if (r < numbers[endIndex]) {
// we've found the minimum, return it without recursing again
return r;
}
// again, no need for else, here
return numbers[endIndex];
}
Now the algorithm only takes 20 calls for an array of size 20, 50 for size 50, 100 for size 100. The fact that you had already called findMin recursively to get the value to compare but were then calling it again to get the same value to return should have been a red flag. In many cases, such unnecessary repetition would merely be a minor annoyance; in this case, it was catastrophic.
Oh, I forgot to mention. The reason entering a negative number triggered the problem: Presumably, you don't always type 100 numbers in. I never did when I tried your program. It's too boring, and you can just end the list by entering a zero. When you allocate the array:
int[] numbers = new int[100];
The array is filled with zeros. So, if you enter ten numbers, the rest of the array will be zeros, and when we get to this line in the first call to findMin:
if (findMin(numbers, startIndex, endIndex - 1) < numbers[endIndex])
The number at the end will be zero, which is also the min. So we only recurse once, not twice. That will happen for most of the recursive calls, too; it will happen for all the ones at the long tail of zeros at the end of the array. It will only be when we get down into the entries where the user has actually entered a value where we will see the doubly-recursive behavior. If the user only enters about 10 numbers, we're safe.
But if the user enters even a single negative number, then that becomes the minimum and the zeros don't protect us. We hit the double recursion on every call, except for the one where numbers[endIndex] holds that negative number. Come to think of it, the reason I got 2^(x-1) + 2^(x-2) - 1 instead of just 2^x - 1 is because I always put the negative number in the second position in the array. So, depending on where the minimum value is, you could get performance better, or even worse, than what I describe above.

Changing numbers places in java

Can anyone please learn me how to change this number 5486 to 4568 ? I need to change two pairs of numbers places. Any ideas please?
My code :
public Number shiftRight(int n) {
int length = (getNumOfDigits()+MINUSONE);
length = (int) Math.pow(TEN, length);
for (int i=0; i<n; i++){
int m=num%TEN;
num=(m*length) + (num/TEN);
}
return new Number(num);
}
public int shiftRightDistance(Number other){
int max = getNumOfDigits();
for (int i=0;i<max;i++)
{
if(compareTo(shiftRight(i))==ZERO)
{
return i;
}
}
return MINUSONE;
}
public Number swapPairs() {
}
}
The simplest (and least confusing) thing might be to convert the number to a char array, swap pairs of characters, and then convert back to a number. You can use String.valueOf(int), String.toCharArray(), new String(char[]) and Integer.valueOf(String) to put that together.
Alternatively, you can build on the following method that swaps the digits of a non-negative number less than 100:
private int swapDigitsLessThan100(int n) {
return 10 * (n % 10) + n / 10;
}
The way to build on that would be to extract every pair of digits from the original number, working recursively. The following deals with numbers that are an even number of digits long:
public int swapDigits(int n) {
if (n == 0) {
return 0;
return 100 * swapDigits(n / 100) + swapDigitsLessThan100(n % 100);
}
With this code, if n is an odd number of digits, the result will be to use a leading 0 as an additional digit.

Categories

Resources