Best way to count 1's of a binary number [duplicate] - java

This question already has answers here:
Count the number of set bits in a 32-bit integer
(65 answers)
Closed 7 years ago.
Doing a question on codility and was Asked to take two numbers and get the product. Then get the binary repesentation of that number and count the number of one's that are in the binary number.
My code is
return method(int a, int b)
{
int count=0;
int num;
num = a* b;
while(num>0)
{
if(num %2 ==1)
{
count++;
}
num = num >> 1;
}
return count;
}
Yet it only gives 50% correctness. Can anyone explain this. Is there something i missed that i should be aware off.

Using the modulo operator won't correctly count the bits in a negative number. Use "num & 1" instead. Also, make sure you're using unsigned right shifts or a negative number may produce an infinite loop.
And as Lashane said, use a 64 bit product if possible.

Related

How to find the smallest number with just 0 and 7 which is divided by a given number? [duplicate]

This question already has answers here:
How to find the smallest number with just 0 and 1 which is divided by a given number?
(11 answers)
Closed 7 years ago.
This is one of algorithmic problem I encountered in one of interview. Unable to figure out how to solve it in most efficient way.
Here is my suggested code. It finds the smallest number with 0 and 7 (except the number 0) within the long range.
In this case, I'm looking for the result for 11.
public class Class007
{
static long NUM = 11;
public static void main(String[] args)
{
//NUM is the given number
//find007() finds the smallest number with 0 & 7 that is divided by NUM
System.out.print(find007(NUM));
}
static long find007(long n){
if(is007(n))
return n;
if(n+NUM<n)
return 0;
return find007(n+NUM);
}
static boolean is007(long n){
while(n!=0 && (n%10==0 || n%10==7))
n=n/10;
return n==0;
}
}
According by THIS QUESTION, in http://oeis.org/ you can find this class of number sequences: Check your's here.
a(n) = min{A204094(k): k > 0 and A204094(k) mod n = 0}
Simply adapt the algorithm to fit your needs.

Project euler 10 help. Whats wrong with this code? the sum flips to negative [duplicate]

This question already has answers here:
How does Java handle integer underflows and overflows and how would you check for it?
(12 answers)
Closed 8 years ago.
// finding sum of all primes under 2 million
public class lll {
public static void main(String[] args) {
int a = 2;
int b = 0;
int c = 0;
while (a < 2000000) {
int i = 1;
for (i = 1; i * i <= a; i++) {
if (a % i == 0)
//if factor is found of number a b goes up 1
{
b++;
}
}
// all primes have only one factor <= sqrt (1)
if (b == 1)
// if b =1 , a is prime so c+=a
{
c += a;
}
//reset b and add one to a to move on
b = 0;
a++;
// for error checking see description
System.out.println(c);
}
System.out.println(c);
}
}
Im trying to make a code to find the sum of all primes under 2 million, heres what i have it gives 1179908154, but this is not right, c is supposed to be the sum. I tried getting c after every check of number being prime and it shows that during the running of this code it lips from positive to negative and then back again. it makes no sense a starts at 1, a goes up c starts at 0, it goes up by a so how is c getting negative (a is never negative), please help me, I have managed to used this method of prime checking to correctly get the 10001st prime, it worked then.
A 32 bit integer can only hold numbers below about 2 billion. If you try to add more to that number (accessible by Integer.MAX_VALUE), you will end up "flipping" to negative numbers. Try out the following code:
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MAX_VALUE + 1);
System.out.println(Integer.MIN_VALUE);
So your problem is that integers aren't big enough! How can you solve this? The simplest way is to use a long instead of an int. Hypothetically, what if a long isn't even big enough? Then you can use a class like BigInteger, which isn't constrained to a fixed number of bits, and can grow as necessary.
Well, you declared c as an int which in java has a max value of 2,147,483,647 . The sum of all primes less than 1 million is 37,550,402,023, so Im thinking you are surpassing the data storage for int which is why its flipping negative on you.
My guess is that it has something to do with memory. In java the maximum number an integer can hold is 2147483647. So if the sum of primes goes over this number, it will loop back to -2147483648 and continue counting. Try making your variable c a long instead.

Which data type or data structure to choose to calculate factorial of 100?

I thought of writing a program to evaluate factorial of a given integer.
Following basics I wrote the below code in java :
long fact(int num){
if(num == 1)
return 1;
else
return num*fact(num-1);
}
But then I realized that for many integer input the result may not be what is desired and hence for testing directly gave input as 100.
My doubt was true as Result I got was "0"(cause result might be out of range of long).
So,I am just curious and eager to know as how may I make my program work for inputs<=150.
I would appreciate any valid solution in C programming language or Java.
BigInteger is your class. It can store integers of seemingly any size.
static BigInteger fact(BigInteger num) {
if (num.equals(BigInteger.ONE))
return BigInteger.ONE;
else
return num.multiply(fact(num.subtract(BigInteger.ONE)));
}
If you're not after a naive approach of factorial computation, you should do some research into the problem. Here's a good overview of some algorithms for computing factorials: http://www.luschny.de/math/factorial/conclusions.html
But like the other answers suggest, your current problem is that you need to use a large number implementation (e.g. BigInt) instead of fixed size integers.
In C Language, you can use array to store factorial of large number.
my reference: Calculate the factorial of an arbitrarily large number, showing all the digits. it very helpful post.
I made small changes in code to convert into C.
int max = 5000;
void factorial(int arr[], int n){//factorial in array
if (!n) return;
int carry = 0;
int i=max-1;
for (i=max-1; i>=0; --i){
arr[i] = (arr[i] * n) + carry;
carry = arr[i]/10;
arr[i] %= 10;
}
factorial(arr,n-1);
}
void display(int arr[]){// to print array
int ctr = 0;
int i=0;
for (i=0; i<max; i++){
if (!ctr && arr[i])
ctr = 1;
if(ctr)
printf("%d", arr[i]);
}
}
int main(){
int *arr = calloc(max, sizeof(int));
arr[max-1] = 1;
int num = 100;
printf("factorial of %d is: ",num);
factorial(arr,num);
display(arr);
free(arr);
return 0;
}
And its working for 100! see: here Codepad
I would like to give you links of two more useful posts.
1) How to handle arbitrarily large integers suggests GPU MP
2) C++ program to calculate large factorials
In java you have the BigInteger that can store arbitrary big integers. Unfortunately there is no equivelent in C. You either have to use a third-party library or to implement big integers on your own. Typical approach for this is to have a dynammically-allocated array that stores each of the digits of the given number in some numeric system(usually base more than 10 is chosen so that you reduce the total number of digits you need).
A decimal (base 10) digit takes about 3.3 bits (exactly: log(10)/log(2)). 100! is something like 158 digits long, so you need 158 * 3.3 = 520 bits.
There is certainly no built in type in C that will do this. You need some form of special library if you want every digit in the factorial calculation to be "present".
Using double would give you an approximate result (this assumes that double is a 64-bit floating point value that is IEEE-754 compatible, or with similar range - the IEEE-754 double format will give about 16 decimal digits (52 bits of precision, divided by the log(10)/log(2) like above). I believe there are more than 16 digits in this value, so you won't get an exact value, but it will calculate some number that is within a 10 or more digits.

Dealing with overflow in Java without using BigInteger

Suppose I have a method to calculate combinations of r items from n items:
public static long combi(int n, int r) {
if ( r == n) return 1;
long numr = 1;
for(int i=n; i > (n-r); i--) {
numr *=i;
}
return numr/fact(r);
}
public static long fact(int n) {
long rs = 1;
if(n <2) return 1;
for (int i=2; i<=n; i++) {
rs *=i;
}
return rs;
}
As you can see it involves factorial which can easily overflow the result. For example if I have fact(200) for the foctorial method I get zero. The question is why do I get zero?
Secondly how do I deal with overflow in above context? The method should return largest possible number to fit in long if the result is too big instead of returning wrong answer.
One approach (but this could be wrong) is that if the result exceed some large number for example 1,400,000,000 then return remainder of result modulo
1,400,000,001. Can you explain what this means and how can I do that in Java?
Note that I do not guarantee that above methods are accurate for calculating factorial and combinations. Extra bonus if you can find errors and correct them.
Note that I can only use int or long and if it is unavoidable, can also use double. Other data types are not allowed.
I am not sure who marked this question as homework. This is NOT homework. I wish it was homework and i was back to future, young student at university. But I am old with more than 10 years working as programmer. I just want to practice developing highly optimized solutions in Java. In our times at university, Internet did not even exist. Today's students are lucky that they can even post their homework on site like SO.
Use the multiplicative formula, instead of the factorial formula.
Since its homework, I won't want to just give you a solution. However a hint I will give is that instead of calculating two large numbers and dividing the result, try calculating both together. e.g. calculate the numerator until its about to over flow, then calculate the denominator. In this last step you can chose the divide the numerator instead of multiplying the denominator. This stops both values from getting really large when the ratio of the two is relatively small.
I got this result before an overflow was detected.
combi(61,30) = 232714176627630544 which is 2.52% of Long.MAX_VALUE
The only "bug" I found in your code is not having any overflow detection, since you know its likely to be a problem. ;)
To answer your first question (why did you get zero), the values of fact() as computed by modular arithmetic were such that you hit a result with all 64 bits zero! Change your fact code to this:
public static long fact(int n) {
long rs = 1;
if( n <2) return 1;
for (int i=2; i<=n; i++) {
rs *=i;
System.out.println(rs);
}
return rs;
}
Take a look at the outputs! They are very interesting.
Now onto the second question....
It looks like you want to give exact integer (er, long) answers for values of n and r that fit, and throw an exception if they do not. This is a fair exercise.
To do this properly you should not use factorial at all. The trick is to recognize that C(n,r) can be computed incrementally by adding terms. This can be done using recursion with memoization, or by the multiplicative formula mentioned by Stefan Kendall.
As you accumulate the results into a long variable that you will use for your answer, check the value after each addition to see if it goes negative. When it does, throw an exception. If it stays positive, you can safely return your accumulated result as your answer.
To see why this works consider Pascal's triangle
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
which is generated like so:
C(0,0) = 1 (base case)
C(1,0) = 1 (base case)
C(1,1) = 1 (base case)
C(2,0) = 1 (base case)
C(2,1) = C(1,0) + C(1,1) = 2
C(2,2) = 1 (base case)
C(3,0) = 1 (base case)
C(3,1) = C(2,0) + C(2,1) = 3
C(3,2) = C(2,1) + C(2,2) = 3
...
When computing the value of C(n,r) using memoization, store the results of recursive invocations as you encounter them in a suitable structure such as an array or hashmap. Each value is the sum of two smaller numbers. The numbers start small and are always positive. Whenever you compute a new value (let's call it a subterm) you are adding smaller positive numbers. Recall from your computer organization class that whenever you add two modular positive numbers, there is an overflow if and only if the sum is negative. It only takes one overflow in the whole process for you to know that the C(n,r) you are looking for is too large.
This line of argument could be turned into a nice inductive proof, but that might be for another assignment, and perhaps another StackExchange site.
ADDENDUM
Here is a complete application you can run. (I haven't figured out how to get Java to run on codepad and ideone).
/**
* A demo showing how to do combinations using recursion and memoization, while detecting
* results that cannot fit in 64 bits.
*/
public class CombinationExample {
/**
* Returns the number of combinatios of r things out of n total.
*/
public static long combi(int n, int r) {
long[][] cache = new long[n + 1][n + 1];
if (n < 0 || r > n) {
throw new IllegalArgumentException("Nonsense args");
}
return c(n, r, cache);
}
/**
* Recursive helper for combi.
*/
private static long c(int n, int r, long[][] cache) {
if (r == 0 || r == n) {
return cache[n][r] = 1;
} else if (cache[n][r] != 0) {
return cache[n][r];
} else {
cache[n][r] = c(n-1, r-1, cache) + c(n-1, r, cache);
if (cache[n][r] < 0) {
throw new RuntimeException("Woops too big");
}
return cache[n][r];
}
}
/**
* Prints out a few example invocations.
*/
public static void main(String[] args) {
String[] data = ("0,0,3,1,4,4,5,2,10,0,10,10,10,4,9,7,70,8,295,100," +
"34,88,-2,7,9,-1,90,0,90,1,90,2,90,3,90,8,90,24").split(",");
for (int i = 0; i < data.length; i += 2) {
int n = Integer.valueOf(data[i]);
int r = Integer.valueOf(data[i + 1]);
System.out.printf("C(%d,%d) = ", n, r);
try {
System.out.println(combi(n, r));
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
Hope it is useful. It's just a quick hack so you might want to clean it up a little.... Also note that a good solution would use proper unit testing, although this code does give nice output.
You can use the java.math.BigInteger class to deal with arbitrarily large numbers.
If you make the return type double, it can handle up to fact(170), but you'll lose some precision because of the nature of double (I don't know why you'd need exact precision for such huge numbers).
For input over 170, the result is infinity
Note that java.lang.Long includes constants for the min and max values for a long.
When you add together two signed 2s-complement positive values of a given size, and the result overflows, the result will be negative. Bit-wise, it will be the same bits you would have gotten with a larger representation, only the high-order bit will be truncated away.
Multiplying is a bit more complicated, unfortunately, since you can overflow by more than one bit.
But you can multiply in parts. Basically you break the to multipliers into low and high halves (or more than that, if you already have an "overflowed" value), perform the four possible multiplications between the four halves, then recombine the results. (It's really just like doing decimal multiplication by hand, but each "digit" is, say, 32 bits.)
You can copy the code from java.math.BigInteger to deal with arbitrarily large numbers. Go ahead and plagiarize.

How to test if an array contains a pair of numbers whose product is odd?

How can I write a function that takes an array of integers and returns true if their exists a pair of numbers whose product is odd?
What are the properties of odd integers? And of course, how do you write this function in Java? Also, maybe a short explanation of how you went about formulating an algorithm for the actual implementation.
Yes, this is a function out of a textbook. No, this is not homework—I'm just trying to learn, so please no "do your own homework comments."
An odd number is not evenly divisible by two. All you need to know is are there two odd numbers in the set. Just check to see if each number mod 2 is non-zero. If so it is odd. If you find two odd numbers then you can multiply those and get another odd number.
Note: an odd number multiplied by an even number is always even.
The product of two integers will be odd only if both integers are odd. So, to solve this problem, just scan the array once and see if there are two (or more) odd integers.
EDIT: As others have mentioned, you check to see if a number is odd by using the modulus (%) operator. If N % 2 == 0, then the number is even.
Properties worth thinking about:
Odd numbers are not divisible by 2
Any number multiplied by an even number is even
So you can re-state the question as:
Does the array contain at least two integers that are not divisible by 2?
Which should make things easier.
You can test for evenness (or oddness) by using the modulus.
i % 2 = 0 if i is even; test for that and you can find out if a number is even/odd
A brute force algorithm:
public static boolean hasAtLeastTwoOdds(int[] args) {
int[] target = args; // make defensive copy
int oddsFound;
int numberOddsSought = 2;
for (int i = 0; i < target.length; i++) {
if (target[i] % 2 != 0) {
if (oddsFound== numberOddsSought) {
return true;
}
oddsFound++;
}
}
return false;
}
Thank you for your answers and comments.
I now understand well how to test whether an integer is odd. For example, this method is a neat way of doing this test without using multiplication, modulus, or division operators:
protected boolean isOdd(int i) {
return ( (i&1) == 1);
}
With your help, I now realize that the problem is much simpler than I had expected. Here is the rest of my implementation in Java. Comments and criticism are welcome.
protected boolean isOddProduct(int[] arr) {
int oddCount = 0;
if (arr.length < 2)
throw new IllegalArgumentException();
for (int i = 0; i <= arr.length-1; i++) {
if (isOdd(arr[i]))
oddCount++;
}
return oddCount > 1;
}
I wonder if there exists any other ways to perform this test without using *, % or / operators? Maybe I'll ask this question in a new thread.

Categories