Write a method named hasSharedDigit with two parameters of type int.
Numbers are between 10 and 99
The method should return true if there is a digit that appears in both numbers, such as 2 in 12 and 23; otherwise, the method should return false.
I have a solution, but don't quite understand how it works. I need an English explanation.
public class SharedDigit {
public static boolean hasSharedDigit(int numA,int numB){
if((numA<10||numA>99)||(numB<10||numB>99)){
return false;
}
int realNumB=numB;
while(numA>0){
int numADig=numA%10;
while(numB>0){
int numBDig=numB%10;
if(numADig==numBDig){
return true;
}
numB=numB/10;
}
numA=numA/10;
numB=realNumB;
}
return false;
}
}
I don't understand how this code is checking all possibilities of matching numbers
This here:
while(numA>0){
int numADig=numA%10;
uses the modulo operator to "get" the last digit of a number, see here for more information. So this first step gets you the "3" from 13 for example.
Later, you do:
numA=numA/10;
That turns 13 into 1 (int division)! That initial loop condition before ensures that you stop when you did 13 / 10 .. and then 1 / 10.
So this loops turns 13 into 3, then 1, and then stops.
And the same "method" is used to get the digits of the second number. And as soon as you find a digit in both numbers, you can return true.
Otherwise, if you walked trough all digits of the first number, and compared them against all digits in the second number ... no match, return false.
The real answer here, btw: when you do not understand what code does:
use a search engine to research all the things in the source you do not know
use a debugger, or simple System.out.printl() statements to enable yourself to observe what the code is doing
then finally, when all of that fails, and leaves you with doubts, then come here and ask for help
Have a look on my correct solution.
public class SharedDigit {
public static boolean hasSharedDigit (int one, int two) {
int modulusOne = one % 10;
int modulusTwo = two % 10;
int divisionOne = one / 10;
int divisionTwo = two / 10;
if ((one < 10 || one > 99) || (two < 10 || two > 99)) {
return false;
} else if (one == two){
return true;
} else if (modulusOne == modulusTwo){
return true;
} else if (divisionOne == divisionTwo){
return true;
} else if (divisionOne == modulusTwo){
return true;
} else if (divisionTwo == modulusOne){
return true;
} else {
return false;
}
}
}
Related
Basically, I am trying to write a method where a number is inputted and if there are more odd digits than even digits in the number, it returns "true", and else, false. I think I need to use tail recursion but I cannot figure it out.
public static boolean moreOddThanEven(int x) {
if (x == 0) {
return false;
}
if (x % 2 == 0) {
return moreOddThanEven(x / 10);
} else {
return moreOddThanEven(x / 10);
}
}
public static boolean moreOddThanEven2(int x) {
return moreOddThanEvenTR(x, 0, 0);
}
public static boolean moreOddThanEvenTR(int x, int odd, int even) {
if (x == 0) {
return false;
}
if (x%2==0) {
return moreOddThanEvenTR(x / 10, odd, even+1);
}
if (x%2!=0) {
return moreOddThanEvenTR(x / 10, odd+1, even);
}
if (odd <= even) {
return false;
} else {
return true;
}
}
I think using tail recursion is the right idea. Here is my attempt, assuming we can use more than one parameter in the recursive function:
public static boolean compareOddEven(int x, int count) {
//This is when we reach the end of the recursion (ones place).
if(x<10) {
//if odd, add 1, if even subtract 1
count += (x%2==1) ? 1 : -1;
return count>0;
}
else{
int digit = x;
//We use this loop in order to get the leftmost digit and read whether it is odd or even.
//Subsequently, we add or subtract 1 to the count based on the digit's parity and we pass this count into the next recursion in order to keep track.
while (digit > 9) {
digit /= 10;
}
count += (digit%2==1) ? 1 : -1;
//Get rid of the first digit to get next number to use in recursive call.
int removedFirstDigit = x % (int) Math.pow(10, (int) Math.log10(x));
//tail recursion
return compareOddEven(removedFirstDigit, count);
}
}
Explanation. We can accomplish this with just one method if we keep track of the count of odd and even digits the second parameter of the method. It will be less cumbersome to keep track of the count rather than keeping track of both counts of the odd and even numbers (and avoids the comparisons at the end which would not make it a tail recursion).
With this in mind, our approach is to start at the leftmost digit of the number we input and move to the right with each new recursive call. It is possible to start from right and go left in counting the parity of the digits as well.
So with every new recursive call, we pass in the count to the function as an argument. When we finally reach the ones digit, the nonnegativity of the count tells us whether there are more odd or even digits. To see this more clearly, I recommend printing out some of the arguments right before the recursive call is made.
Further note that when we reach the ones place, the truth value of count>0 will be propagated up the chain of recursive calls to give the final result that we desire.
Example call:
System.out.println(compareOddEven(21468233, 0));
Output:
false
There is a simple reason why you are stuck: you have to count the evens/odds like in 77778888888999. In fact you need to count the sum of (odds - evens), the oddity.
public static boolean moreOddThanEven(int x) {
assert x >= 0;
return x != 0 && oddity(x) > 0;
}
private static int oddity(int x) {
if (x == 0) {
return 0;
}
if (x % 2 == 0) {
return oddity(x / 10) - 1;
} else {
return oddity(x / 10) + 1;
}
}
Recursion is not needed (nor is more than one line):
public static boolean moreOddThanEven(int x) {
return (""+x).replaceAll("[02468]", "").length() > ((int) Math.log10(x)+1) / 2;
}
or the longer, but non-mathy version:
public static boolean moreOddThanEven(int x) {
return (""+x).replaceAll("[02468]", "").length() > ((int) (""+x).replaceAll("[13579]", "").length();
}
If you have an easier time thinking about loops than tail recursion, it's worth knowing that you can translate any loop into tail recursion (and vice versa, but that's different topic). First, we need to get the loop into this shape:
initialize a, b, ...
while (<some condition on a, b, ...>) {
Update a, b, ... using old values of a, b, ...
}
return <any function of a, b ...>
it translates to:
TypeOfReturn while_loop(TypeOfA a, TypeOfB b, ...) {
if (!(<some condition on a, b, ...>)) {
return <any function of a, b, c ...>;
}
Update a, b, ... using old values of a, b, ...
return while_loop(a, b, ...);
}
Let's apply this to your problem. As a loop:
// x is the input
int oddMinusEven = 0;
while (x) {
oddMinusEven += 2 * (x % 2) - 1;
x /= 10;
}
return oddMinusEven > 0;
We get:
bool hasMoreOddThanEvenDigits(int x, int oddMinusEven) {
if (!x) return oddMinusEven > 0;
oddMinusEven += 2 * (x % 2) - 1;
x /= 10;
return hasMoreOddThanEvenDigits(x, oddMinusEven);
}
We can clean this up a bit to make it less verbose:
int hasMoreOddThanEvenDigits(int x, int oddMinusEven) {
return x ? hasMoreOddThanEvenDigits(x / 10, oddMinusEven + 2 * (x % 2) - 1) : oddMinusEven > 0;
}
We run the loop with a "top level" function call that initializes variables:
return getMoreOddThanEvenDigits(x, 0) > 0;
It's fun to see what a good compiler does with the two codes. As you'd expect, they lead to nearly identical machine code. If we can do a rule-based transformation, so can the compiler.
I'm having trouble with this problem. I am supposed to find the amount of even digits in a number.
So for example, if the number is 146, then there are 2 even digits.
And if the number is 802, then there are 3 even digits.
I was told that n % 10 is the value of the rightmost digit. n / 10 contains all of the digits except the rightmost digit.
public static int countEvenDigits(int n) {
int rightDigit = n % 10;
int count= 0;
if (rightDigit / 10 == 0) {
count++;
}
return countEvenDigits(count);
}
With recursion, you can do it like this
int calcRec(int num) {
if (num / 10 == 0) {
return num % 2 == 0 ? 1 : 0;
}else{
return (num % 10 % 2 == 0? 1:0)+calcRec(num/10);
}
}
But its not suitable case for using recursion.
Another answer:
public static int countEvenDigits(int number) {
if (number == 0) return 0;
int lastDigit = number % 10;
int firstDigits = number / 10;
if (lastDigit % 2 == 0) {
return 1 + countEvenDigits(firstDigits);
} else {
return 0 + countEvenDigits(firstDigits);
}
}
Recursion always needs one or more "base case"s, where recursion stops (in this case, no digits left); and one or more "recursive cases" where you continue to work with a smaller problem (with the firstDigits).
I agree with #kimreik that this is not a good use of recursion (as the problem could be better solved with a while-loop); but it is a very typical example when starting to learn to program recursion, as I suspect the OP is doing.
Ok so the idea of using recursion to process a series is that you define a function that process and removes one element from the set. Seeing as you are interested in digits you have 2 options to define your set from a given int.
The first option is to cast the int to a string and cast each character back into an int. Which is what I implemented below
Alternatively you could do division by your base (10) to the power of the significance of the digit (0 being the right most digit and counting left.) Or more eloquently as kimreik reducing the number by integer division sequentially. (142 / 10 / 10 == 142 / 100 == 1 == "142"[0])...
The syntax for converting your integer to a string is Integer.toString(int). This will be useful as it allows us to access each digit without doing any math and also allows us to take sub-strings which we can pass to the next instance of our recursive method.
Now that we have our array to process we need to address the fundamentals of recursion. Recursion has three parts. These parts are as follows, some starting state or initial values, a base case and a recursive step.
For this problem we must set our initial values for the count of even digits and we will be given a string to process. We will start our count at 0 but it will be a variable passed to each call to our method.
Our base case is the empty sting, that is a blank number. Which contains 0 even numbers. Because we are recurring towards an empty set this type of algorithm is called reductive.
Now our recursive step is where everything really happens. It must read a digit from our string and then remove it from the string by passing the remaining digits to the next instance of the function.
Now that we know what we need to do what does out function look like?
public class HelloWorld{
public static int recursiveGetEvenDigits(String arg){
int count = 0;
if(arg.length()<1){
return(0); // base case
}
else{
count = Character.getNumericValue(arg.charAt(0))%2 == 0 ? 1 : 0; //If else shorthand
return(count+recursiveGetEvenDigits(arg.substring(1)));
}
}
public static int getEvenDigits(int n){ // provide user arguments
return(recursiveGetEvenDigits(Integer.toString(n))); // set initial conditions
}
public static void main(String []args){
System.out.println(getEvenDigits(142));
}
}
Just to be funny the whole if else logic could be reduced to one line again with the same shorthand I used above.
public class HelloWorld{
public static int recursiveGetEvenDigits(String arg){
return arg.length() < 1 ? 0 : (Character.getNumericValue(arg.charAt(0)) % 2 == 0 ? 1 : 0)+recursiveGetEvenDigits(arg.substring(1));
}
public static int getEvenDigits(int n){ // provide user arguments
return(recursiveGetEvenDigits(Integer.toString(n))); // set initial conditions
}
public static void main(String []args){
System.out.println(getEvenDigits(142));
}
}
prints 2
here is a quick pseudo code
function sumEven(int num){
if(num==0)
return 0;
int var =num%10;
if(var % 2)
return var+(num/10)
else
return 0+(num/10)
}
I need to build a method that calculates prime numbers.
I'm testing it and it's giving me the wrong answers and I don't know how to solve it! For example, it returns true to 98262679 instead of false. Where is my mistake?
public static boolean itsPrime(int nbTest){ // Tests for prime numbers method
boolean prime = false;
if (nbTest <= 1){
return false;
} else if (nbTest == 2){ // Two is prime
return true;
} else if ((nbTest != 2) && (nbTest % 2 == 0)){ // Evens except number 2
return false; // are not prime
} else if (nbTest % 2 != 0){ // For all remaining odds
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
}
return prime;
}
I'm learning Java and my professor asked us to construct the method itsPrime was based on this:
For the first subtask, write a function `itsPrime` that takes an `int`
as argument and returns a `boolean`, `true` if the argument integer is prime
and `false` otherwise.
To test whether an integer x is prime, one can proceed as follows:
all integers less than or equal to 1 are not prime;
2 is prime;
all other even integers are not prime;
for all remaining integers (obviously odd), search for a divisor:
loop from 3 to the square root of the integer x (The square root of x can
be computed as ‘‘Math.sqrt(x)'' in Java.); if the remainder of the integer
division of x by the loop index is zero, then x is not prime;
if all remainders were non-zero at the end of the loop, then x is prime;
I know the answer is there somewhere in all the answers above, but I think that each require an explanation.
Here's a summary of all the enhancements you could make to your code:
1) Don't declare a boolean to return, since you are already returning true or false throughout your code. Remove this line from your code (call it [1]):
boolean prime = false;
You'll see why after you've fixed the rest of your function. Comment it out if desired, for now.
2) In your second else if, let's call it [2], you have:
else if ((nbTest != 2) && (nbTest % 2 == 0)){
return false;
}
You already checked if nbTest is 2 in your first else if, so you don't need to check if it's not 2 again. If it entered the first if else, your function will return true. When a function returns, it is done. It returns the value to the caller and the rest of the code is not executed.
Thus, you may replace that second if else, [2], with:
else if (nbTest % 2 == 0) { // all other even integers are not prime
return false;
}
3) If you enter third else if, this means that the rest of the code above already executed, and it either returned, or the program continued.
You may replace that third else if (nbTest % 2 != 0){ for:
else {
4) This is the one error that you really have to make your function return the wrong answer (call this snippet [4]):
if (nbTest % i == 0){
prime = false;
If you find that the number you are testing is divisible (i.e. the remainder is zero), you are done. You definitely know that it is not prime.
You may replace this code, [4], with:
if(nbTest % counter == 0) {
return false;
}
Thus, returning false. It is not a number. And the function does not keep executing. Your error was continuing execution after the function finds out that your input is not prime.
Finally, you may leave your return true at the end of the function body. If the function never returned from the previous tests, or from the loop, it has to be a prime number. Remember that first line I told you to remove? The boolean declaration? Since you never return a value from a variable, you just return true or false, you don't need that [1] line.
As an extra, a good read on finding prime numbers, which you might want to share with your professor:
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
You should stop once you here:
if (nbTest % i == 0){
return false;
}
Delete the prime variable (it is an unnecessary step, see below).
Change the for loop:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2){
if (nbTest % i == 0){
prime = false;
} else {
prime = true;
}
}
To this:
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2)
if (nbTest % i == 0)
return false;
This simply breaks out of the function early if it isn't prime (if a factor has been found).
You shouldn't keep testing for primality once prime has been set to false for a number.
Replace:
if (nbTest % i == 0){
prime = false;
with:
if (nbTest % i == 0){
return false;
And the last test is useless, you can just keep a basic else:
else if (nbTest % 2 != 0){ => else {
Your for loop is not correct.
A prime number is a number which is divisible by 1 and itself only. So, if a number A is divisible by any other number except 1 and itself, then A is a nonprime.
Just replace your for loop with the one below
for(int i = 3; i <= Math.sqrt(nbTest); i = i+2) {
if (nbTest % i == 0)
return false;
}
Once it is found that nbTest is divisible by some number, there is not point in continuing the loop. Return `nbTest is nonprime, then and there.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How would you modify the below to print out all prime numbers from 1-100? The below has an issue with the number 2 coming back as not prime. The if(i%number == 0) condition is met for the number 2 as 2%2 is returned as 0.
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
for(int i=1; i<=100; i++){
if(isPrime(i)){
System.out.println(i + " is a prime number");
}else{
System.out.println(i + " is not a prime number");
}
}
}
public static boolean isPrime(int number){
for(int i=2; i<=number; i++){
if(i%number == 0){
return false;
}else{
return true;
}
}
return false;
}
}
i<=number
You shouldn't be checking whether the number is divisible by itself.
You also have another problem:
}else{
return true;
}
You're returning true as soon as you find a single non-divisible number, even if it does have factors later.
Here is an algorithm for determining whether or not a number is prime.
Is the number less than 2? If so, return false.
Is the number 2 or 3? If so, return true.
Is the number 4? If so, return false.
Take the square root of the number, rounded up to the next integer. This is optional for small prime numbers, but speeds up the determination for larger numbers.
Loop from 5 to the square root of the number (or the number), incrementing by 2.
Divide the loop number by the prime numbers determined so far.
If the modulus of the division is zero, return false.
If the loop is completed, return true.
You've got a couple issues here. Firstly, when checking whether or not a number is prime, never check every number up to the actual number being checked for primality. A check of all primes up to the square root of the number will always be sufficient.
To fix that error look at your for loop condition and edit it accordingly:
for(int i=2; i<=number; i++)
Secondly, when a function returns it stops. Currently with your if/else statement:
if (i%number == 0) {
return false;
} else {
return true;
}
If this condition goes to the else statement even once it will return true, you want to make sure you only actually return true when you've checked all of the numbers you intend to.
Additionally I don't think you've carefully considered what you base case is. What you are saying with your last line is that if everything previously slipped through the cracks then it should assume the number isn't prime. Think about it and I'm sure you'll be able to figure it out.
This will work. 2 is a special case when testing for primes. If you start to search a larger and larger...you might want to look at the sieve of eratosphenes.
Every prime number is a multiple of another number. Take 3 for example. Using the sieve, if you find 3 to be prime it will then 'ignore' all multiples of 3 thus reducing the amount of time taken to find consequent primes. It speeds things up...ALOT :)
public class JavaApplication47 {
public static void main(String[] args) {
for(int i=1; i<=100; i++){
if(isPrime(i)){
System.out.println(i + " is a prime number");
}else{
// System.out.println(i + " is not a prime number");
}
}
}
public static boolean isPrime(int n) {
for(int i=2; 2*i<n; i++) {
if(n%i==0)
return false;
}
return true;
}
}
SIEVE EXAMPLE - NOT IMPLEMENTED - Can be used for reference and understanding.
static boolean [] allPrimes = new boolean[10000];
public static void fillTheSieve(){
Arrays.fill(allPrimes, true);
allPrimes[0] = allPrimes[1] = false; //1 and 0 are false. winning
for (int i = 2; i < allPrimes.length; i++) {
//check if prime, if so getmultiples and declae false
if(allPrimes[i]){
for (int j = 2; i*j<allPrimes.length; j++) {
allPrimes[i*j] = false;
}
}
}
}
The definition of a prime number specifically states that one cannot be a prime number.
That means that isPrime(1) should return false. Which your implementation does.
But isPrime(2) should return true. Which your implementation does not. It does not because (2 % 2 == 0) and you are checking all numbers from 2 to N, not from 2 to N-1. The last number, N, will always yield a zero remainder (N % N == 0)
Just a few things to think about when dealing with Primes. You can have a special case for 2 at the start (i.e. something like if(number == 2)...).
In addition to your error in checking all the way to i<=number consider only how far you need to go in order to be certain it is not prime, hints have already been given with i*i or Math.sqrt
Another thing in the increment i++ think about what that entails, I realize this is only for the first 100 primes but you should always be thinking about performance. Do you really have to check all numbers (2,3,4,5,6...) (hint: if you have checked if its divisible by 2 then you dont need to check for 4,6,8 etc..)
Finally with your return statements, consider using a boolean flag that you set to false/true only when you are positive the number is a prime or is not. And you only need to use 1 return statement.
Hope that helps.
Please try this
public static boolean isPrime(int number) {
for(int i = 2; i * i <= number; i++) {
if (i % number == 0) {
return false;
} else {
return true;
}
}
return true;
}
Write a method named hasAnOddDigit that returns whether any digit of a positive integer is odd. Your method should return true if the number has at least one odd digit and false if none of its digits are odd. 0, 2, 4, 6, and 8 are even digits, and 1, 3, 5, 7, 9 are odd digits.
For example, here are some calls to your method and their expected results:
Call Value Returned
hasAnOddDigit(4822116) true
hasAnOddDigit(2448) false
hasAnOddDigit(-7004) true
You should not use a String to solve this problem.
This is my attempt at the question:
public boolean hasAnOddDigit(int num){
int number=0;
while (number > 0) {
number= number % 10;
number = number / 10;
}
if(number%2==0 && num%2==0){
return false;
}else{
return true;
}
}
Called for hasAnOddDigit(4822116) and it gives me a false instead of true.
Your method should check each digit as it goes through the loop, rather than waiting for the loop to complete before making its decision. Currently, the while loop runs the number down to zero, and only then tries to check the value. Naturally, by the time the loop is over, both values are zero, so the return is false.
public boolean hasAnOddDigit(int num){
// You do not need to make a copy of num, because
// of pass-by-value semantic: since num is a copy,
// you can change it inside the method as you see fit.
while (num > 0) {
int digit = num % 10;
if (digit % 2 == 1) return true;
num /= 10;
}
// If we made it through the loop without hitting an odd digit,
// all digits must be even
return false;
}
A recursive version which might be more intuitive for some.
private boolean hasAnOddDigit(int num) {
if (num<10) {
return num%2==0 ? false : true;
} else {
return check(num%10) || check (num/10);
}
}