How to reverse an integer? - java

I have a code to reverse an integer, but it does not work, can't seem to find the bug.
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
} else if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}

Sometimes it is easier and/or better to rewrite instead of debugging.
Write or think of your algorithm in pseudocode where each high level step is then broken down into more pseudocode. Your conditions seem strange and therefore hard to debug.
It is best not to embed a print directly into the heart of a loop. Rather, build a string and return it. Let the caller print a string.
System.out.println (reverseInt (12345));
public static String reverseInt (anInt) {
Initialize a StringBuffer with an empty string.
while (anInt > 0) {
Get last digit by modulo 10 and put in StringBuffer.
Prepend digit in StringBuffer.
Chop off last digit by doing integer divide.
}
return StringBuffer's .toString ();
}
An alternate algorithm would call reverseInt recursively to build an ever growing string.

if and else if both works together in a sequence from top to down
if(true) { execute } else if() { done execute even if condition is true } else { done execute}
if(false) else if(check condition) { if true execute other wise go to next condition}
So on..
in your case, this is going to be solution
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
}
if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}

Related

Digit amount in an integer [duplicate]

This question already has answers here:
Way to get number of digits in an int?
(29 answers)
Closed 24 days ago.
How can I find the amount of digits in an integer? Mathematically, and by using functions if there are any.
I don't really know how to do that, since I'm a somewhat beginner.
Another option would be to do it iteratively by dividing number by 10, until result is 0.
int number = ...;
int count = 1;
while ((number /= 10) != 0) {
count++;
}
In this program we use a for loop without any body.
On each iteration, the value of num is divided by 10 and count is incremented by 1.
The for loop exits when num != 0 is false, i.e. num = 0.
Since, for loop doesn't have a body, you can change it to a single statement in Java as such:
for(; num != 0; num/=10, ++count);
public class Main {
public static void main(String[] args) {
int count = 0, num = 123456;
for (; num != 0; num /= 10, ++count) {
}
System.out.println("Number of digits: " + count);
}
}
There are many ways to calculate the number of digits in a number. The main difference between them is how important performance is to you. The first way is to translate a number into a string and then take its length:
public static int countDigitsFoo(int x) {
if (x == Integer.MIN_VALUE) {
throw new RuntimeException("Cannot invert Integer.MIN_VALUE");
}
if (x < 0) {
return countDigitsFoo(-x); // + 1; if you want count '-'
}
return Integer.toString(x).length();
}
This method is bad for everyone, except that it is easy to write. Here there is an extra allocation of memory, namely the translation of a number into a string. That with private calls to this function will hit performance very hard.
The second way. You can use integer division and sort of go by the number from right to left:
public static int countDigitsBoo(int x) {
if (x == Integer.MIN_VALUE) {
throw new RuntimeException("Cannot invert Integer.MIN_VALUE");
}
if (x < 0) {
return countDigitsBoo(-x); // + 1; if you want count '-'
}
int count = 0;
while (x > 0) {
count++;
x /= 10;
}
return count;
}
but even this method can be improved. I will not write it in full, but I will give part of the code.
P.S. never use this method, it is rather another way to solve this problem, but no more
public static int countDigitsHoo(int x) {
if (x == Integer.MIN_VALUE) {
throw new RuntimeException("Cannot invert Integer.MIN_VALUE");
}
if (x < 0) {
return countDigitsHoo(-x); // + 1; if you want count '-'
}
if (x < 10) {
return 1;
}
if (x < 100) {
return 2;
}
if (x < 1000) {
return 3;
}
// ...
return 10;
}
You also need to decide what is the number of digits in the number. Should I count the minus sign along with this? Also, in addition, you need to add a condition on Integer.MIN_VALUE because
Integer.MIN_VALUE == -Integer.MIN_VALUE
This is due to the fact that taking a unary minus occurs by -x = ~x + 1 at the hardware level, which leads to "looping" on -Integer.MIN_VALUE
In Java, I would convert the integer to a string using the .toString() function and then use the string to determine the number of digits.
Integer digit = 10000;
Integer digitLength = abs(digit).toString().length();

Program to sum the odd digits recursively

Using recursion, If n is 123, the code should return 4 (i.e. 1+3). But instead it is returning the last digit, in this case 3.
public static int sumOfOddDigits(NaturalNumber n) {
int ans = 0;
if (!n.isZero()) {
int r = n.divideBy10();
sumOfOddDigits(n);
if (r % 2 != 0) {
ans = ans + r;
}
n.multiplyBy10(r);
}
return ans;
}
It isn't clear what NaturalNumber is or why you would prefer it to int, but your algorithm is easy enough to follow with int (and off). First, you want the remainder (or modulus) of division by 10. That is the far right digit. Determine if it is odd. If it is add it to the answer, and then when you recurse divide by 10 and make sure to add the result to the answer. Like,
public static int sumOfOddDigits(int n) {
int ans = 0;
if (n != 0) {
int r = n % 10;
if (r % 2 != 0) {
ans += r;
}
ans += sumOfOddDigits(n / 10);
}
return ans;
}
One problem is that you’re calling multiplyBy on n and not doing anything with the result. NaturalNumber seems likely to be immutable, so the method call has no effect.
But using recursion lets you write declarative code, this kind of imperative logic isn’t needed. instead of mutating local variables you can use the argument list to hold the values to be used in the next iteration:
public static int sumOfOddDigits(final int n) {
return sumOfOddDigits(n, 0);
}
// overload to pass in running total as an argument
public static int sumOfOddDigits(final int n, final int total) {
// base case: no digits left
if (n == 0)
return total;
// n is even: check other digits of n
if (n % 2 == 0)
return sumOfOddDigits(n / 10, total);
// n is odd: add last digit to total,
// then check other digits of n
return sumOfOddDigits(n / 10, n % 10 + total);
}

I ran into some problems with Recursion in Java

The task is to implement a program which counts how many different Sums of Primes there are for a given number sumtoBreak.
The Method primeSum should subtract all possible primes currprime from the number sumtoBreak until the sumtoBreak becomes zero and then return (in sum) a one for each possibilty. To account for all possibilities, in each recession step, it calls itself
with sumtoBreak - currprime plus
calls itself with the nextPrime.
My Problem is that java won't return anything unless the sumtoBreak is zero right at the beginning.
Would be glad for any advice!
Here's the code (I know that the parenthesis in the code with the nested if statements are redundant, but I just wanted to make sure, that's not the problem):
Here's the fixed code:
public class PrimeSum {
public static boolean isPrime(int primecandidate) {
int count = 0;
for (int i = 2; i <= primecandidate / 2; i++) {
if (primecandidate % i == 0)
count++;
}
if (count == 0)
return true;
else
return false;
}
public static int nextPrime(int currprime) {
int j = currprime + 1;
while (!isPrime(j))
j++;
return j;
}
public static int primeSum(int sumtoBreak, int currprime) {
if (sumtoBreak == 0) {
return 1;
} else {
if (sumtoBreak < 0 || currprime > sumtoBreak) {
return 0;
} else {
return primeSum(sumtoBreak, nextPrime(currprime)) + primeSum(sumtoBreak - currprime, currprime);
}
}
}
public static void main(String[] args) {
System.out.println(primeSum(Integer.parseInt(args[0]), 2));
}
}
This doesn't answer your question, but corrects an error in your isPrime Method and computes the result much faster:
private static boolean isPrime(final int primecandidate) {
if ( primecandidate < 2) { // 0 & 1 are NOT Prime
return false;
}
if ((primecandidate & 0x1) == 0) { // Even is NOT Prime...
return primecandidate == 2; // ...except for 2 (and 0).
}
for (int i = 2, iMax = (int) Math.sqrt(primecandidate); i <= iMax; i++) {
if (primecandidate % i == 0) {
return false;
}
}
return true;
}
Note the following:
the final argument primecandidate is marked final
it corrects the result for 0 & 1 to false
the method is marked private
the iMax is Sqrt(primecandidate) & not primecandidate / 2
iMax is calculated once, instead of every iteration
I use a strategy I call "if you're done, be done."
Meaning: don't set a flag (in your case count), just get out!
Please note also, there is an apache commons Math3 function...
org.apache.commons.math3.primes.Primes.isPrime(j)
It is significantly slower for smallish values (<= Short.MAX_VALUE)
It is somewhat faster for largeish values (ca. Integer.MAX_VALUE)
There is also a BigInteger.isProbablePrime(...) function, but my Benchmark suggests it is rather slow.
I hope this helps a little?
Some things you might have missed:
in a function, a return statement terminates (break) the function immediatly. So in
if(...) { return ...; }
else {...}
→ else is redundant, as if the condition is true, the function is already terminated (break)
Something like a==0 has a boolean value (true or false). So
if(count==0) { return false; }
else { return true;}
can be shortened to return count!=0;
I recommend to always use braces, because something like if(i==0) ++i; break;, means if(i==0) {++i;}. break; will be called in any case.
public static boolean
isPrime(int n)
{
if(n==0 || n==1) { return false; }
for(int i= 2; i <= n/2; ++i)
{
if(n%i == 0) { return false; } //we know, n is not a prime,
//so function can break here
}
return true; //since for all values of i, the function did not break,
//n is a prime
}
I wish you a lot of motivation to code for the future!

Java: fast way to check if digits in int are in ascending order

I'm writing a program that finds all of the Armstrong numbers in a range between zero and Integer.MAX_VALUE. Time limit is 10 seconds. I've found that the most time-consuming method is the one that narrows the range of numbers to process by picking only those having their digits in ascending order (with trailing zeros if any). It takes about 57 seconds to run on my machine. Is there any way to make it faster?
static boolean isOK(int x)
{
int prev = 0;
while(x > 0)
{
int digit = x % 10;
if((digit > prev || digit == 0) && prev != 0) return false;
x /= 10;
prev = digit;
}
return true;
}
This method reduces the number of numbers to process from 2.147.483.647 to 140.990.
Perhaps instead of sifting through all the ints, just build up the set of numbers with digits in ascending order. I would argue that you probably want a set of strings (and not ints) because it it is easier to build (recursively by appending/ prepending characters) and then later on you need only the individual "digits" for the power test.
My take on the problem, goes to Long.MAX_VALUE (19 digits) in about 6 seconds and all the way to 39 digits in about an hour
One alternative is to construct the set of Armstrong numbers one by one and count them instead of checking every number to see whether it's an Armstrong number or not.
In constructing the whole set, note that when you choose each digit, the set of digits you can choose for the next position is determined, and so on. Two alternatives to implement such a method are recursion and backtracking (which is basically a cheaper way to implement recursion).
This method will not need the use of time-consuming division and remainder operations.
There is very little optimisable code here. It is likely that your time issue is elsewhere. However, one technique comes to mind and that is Memoization.
static Set<Integer> oks = new HashSet<>();
static boolean isOK(int x) {
if (!oks.contains(x)) {
int prev = 0;
while (x > 0) {
int digit = x % 10;
if ((digit > prev || digit == 0) && prev != 0) {
return false;
}
x /= 10;
prev = digit;
}
// This one is OK.
oks.add(x);
}
return true;
}
This trick uses a Set to remember all of the ok numbers so you don't need to check them. You could also keep a Set of those that failed too to avoid checking them again but keeping all integers in a collection is likely to break something.
You perform two divisions. Divisions are slower than multiplications. So is there a way to change a division into a multiplication? Well... yes, there is.
public static boolean isArmstrongNumber(int n) {
int prev = 0;
while (n > 0) {
int quotient = n / 10;
int digit = n - (quotient * 10);
if ((digit > prev || digit == 0) && prev != 0) {
return false;
}
n = quotient;
prev = digit;
}
return true;
}
The following code doesn't deal with trailing zeroes but is worth checking if it looks promising in terms of performance.
static boolean isOK(int x) {
if (x < 10) {
return true;
}
String xs = Integer.toString(x);
for (int i = 1; i < xs.length(); i++) {
if (xs.charAt(i) < xs.charAt(i - 1)) {
return false;
}
}
return true;
}
The following code runs x4 as fast as the original (3 sec. on my laptop) and prints 140990 in 3 sec.
The method isOK is unchanged
public class Main {
public static boolean isOK(int x) {
int prev = 0;
while (x > 0) {
int digit = x % 10;
if (prev != 0 && (digit > prev || digit == 0)) return false;
x /= 10;
prev = digit;
}
return true;
}
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
Set<Integer> candidates = IntStream.range(0, Integer.MAX_VALUE)
.parallel()
.filter(n -> isOK(n))
.boxed()
.collect(Collectors.toSet());
long stop = System.currentTimeMillis() - start;
System.err.printf("%d in %d sec.", candidates.size(), stop / 1000);
}
}
It has been asked on the MIU test, unfortunately, I was not able to solve it, I later worked on it and it worked fine.
static int isAscending(int n){
int rem, rem1, pval = 0; boolean isAsc = true;
while(n != 0){
rem = n % 10;
n /= 10;
rem1 = n % 10;
n /= 10;
if(rem > rem1){
continue;
} else {
isAsc = false;
break;
}
}
if(isAsc == true){
return 1;
} else {
return 0;
}
}

Very simple prime number test - I think I'm not understanding the for loop

I am practicing past exam papers for a basic java exam, and I am finding it difficult to make a for loop work for testing whether a number is prime. I don't want to complicate it by adding efficiency measures for larger numbers, just something that would at least work for 2 digit numbers.
At the moment it always returns false even if n IS a prime number.
I think my problem is that I am getting something wrong with the for loop itself and where to put the "return true;" and "return false;"... I'm sure it's a really basic mistake I'm making...
public boolean isPrime(int n) {
int i;
for (i = 2; i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
The reason I couldn't find help elsewhere on stackoverflow is because similar questions were asking for a more complicated implementation to have a more efficient way of doing it.
Your for loop has a little problem. It should be: -
for (i = 2; i < n; i++) // replace `i <= n` with `i < n`
Of course you don't want to check the remainder when n is divided by n. It will always give you 1.
In fact, you can even reduce the number of iterations by changing the condition to: - i <= n / 2. Since n can't be divided by a number greater than n / 2, except when we consider n, which we don't have to consider at all.
So, you can change your for loop to: -
for (i = 2; i <= n / 2; i++)
You can stop much earlier and skip through the loop faster with:
public boolean isPrime(long n) {
// fast even test.
if(n > 2 && (n & 1) == 0)
return false;
// only odd factors need to be tested up to n^0.5
for(int i = 3; i * i <= n; i += 2)
if (n % i == 0)
return false;
return true;
}
Error is i<=n
for (i = 2; i<n; i++){
You should write i < n, because the last iteration step will give you true.
public class PrimeNumberCheck {
private static int maxNumberToCheck = 100;
public PrimeNumberCheck() {
}
public static void main(String[] args) {
PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();
for(int ii=0;ii < maxNumberToCheck; ii++) {
boolean isPrimeNumber = primeNumberCheck.isPrime(ii);
System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
}
}
private boolean isPrime(int numberToCheck) {
boolean isPrime = true;
if(numberToCheck < 2) {
isPrime = false;
}
for(int ii=2;ii<numberToCheck;ii++) {
if(numberToCheck%ii == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
}
With this code number divisible by 3 will be skipped the for loop code initialization.
For loop iteration will also skip multiples of 3.
private static boolean isPrime(int n) {
if ((n > 2 && (n & 1) == 0) // check is it even
|| n <= 1 //check for -ve
|| (n > 3 && (n % 3 == 0))) { //check for 3 divisiable
return false;
}
int maxLookup = (int) Math.sqrt(n);
for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
if (n % (i+2) == 0 || n % (i+4) == 0) {
return false;
}
}
return true;
}
You could also use some simple Math property for this in your for loop.
A number 'n' will be a prime number if and only if it is divisible by itself or 1.
If a number is not a prime number it will have two factors:
n = a * b
you can use the for loop to check till sqrt of the number 'n' instead of going all the way to 'n'. As in if 'a' and 'b' both are greater than the sqrt of the number 'n', a*b would be greater than 'n'. So at least one of the factors must be less than or equal to the square root.
so your loop would be something like below:
for(int i=2; i<=Math.sqrt(n); i++)
By doing this you would drastically reduce the run time complexity of the code.
I think it would come down to O(n/2).
One of the fastest way is looping only till the square root of n.
private static boolean isPrime(int n){
int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
HashSet<Integer> nos = new HashSet<>();
for(int i=1;i<=square;i++){
if(n%i==0){
if(n/i==i){
nos.add(i);
}else{
nos.add(i);
int rem = n/i;
nos.add(rem);
}
}
}
return nos.size()==2;//if contains 1 and n then prime
}
You are checking i<=n.So when i==n, you will get 0 only and it will return false always.Try i<=(n/2).No need to check until i<n.
The mentioned above algorithm treats 1 as prime though it is not.
Hence here is the solution.
static boolean isPrime(int n) {
int perfect_modulo = 0;
boolean prime = false;
for ( int i = 1; i <= n; i++ ) {
if ( n % i == 0 ) {
perfect_modulo += 1;
}
}
if ( perfect_modulo == 2 ) {
prime = true;
}
return prime;
}
Doing it the Java 8 way is nicer and cleaner
private static boolean isPrimeA(final int number) {
return IntStream
.rangeClosed(2, number/2)
.noneMatch(i -> number%i == 0);
}

Categories

Resources