C(n,r) calculator program doesn't work - java

I made a C(n,r) calculator using java Netbeans JFrameform.
here is the frame
Here is the code :-
private void lllActionPerformed(java.awt.event.ActionEvent evt) {
int n=Integer.parseInt(t1.getText());
int r=Integer.parseInt(t2.getText());
int s=1;
for(int i=1;i<=n;i=i+1){
s=i*s;
}
int p=1;
for(int j=1;j<=n-r;j=j+1){
p=j*p;
}
int q=1;
for(int k=1;k<=r;k=k+1){
q=k*q;
}
int re=s/(p*q);
t3.setText(" "+re);
}
the code works well for values values of n upto 12. But for 13 and onward , code starts giving wrong answer.
wrong output
why is this happening? Your help is appreciated.

During the calculations the value goes over Integer.MAX_VALUE This is an overflow of arithmetic operation:
Integer overflow can be demonstrated through an odometer overflowing, a mechanical version of the phenomenon. All digits are set to the maximum 9 and the next increment of the white digit causes a cascade of carry-over additions setting all digits to 0, but there is no higher digit to change to a 1, so the counter resets to zero. This is wrapping in contrast to saturating.
In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bits – either larger than the maximum or lower than the minimum representable value.
Try to replace int with long values. It will work with a greater value.
private void lllActionPerformed(java.awt.event.ActionEvent evt) {
int n=Integer.parseInt(t1.getText());
int r=Integer.parseInt(t2.getText());
int s=1;
for(int i=1;i<=n;i=i+1){
s=i*s;
}
long p=1L;
for(int j=1;j<=n-r;j=j+1){
p=j*p;
}
long q=1L;
for(int k=1;k<=r;k=k+1){
q=k*q;
}
long re=s/(p*q);
t3.setText(" "+re);
}
With 14 and 2 as inputs the result is 91.
If you want to have a correct result for big values you have to use a BigInteger that handle:
Immutable arbitrary-precision integers

Try using this
private void lllActionPerformed(java.awt.event.ActionEvent evt) {
int n=Integer.parseInt(t1.getText());
int r=Integer.parseInt(t2.getText());
if (r > n / 2) r = n - r; // because C(n, r) == C(n, n - r)
long ans = 1;
int i;
for (i = 1; i <= r; i++) {
ans *= n - r + i;
ans /= i;
}
t3.setText(" "+ans);
}

Related

Rounding integers to one significant digit

I want to round down an int in Java, what i mean is, if I have an int 45678, i want to convert that int into 40000
this is how im calling it
int den = placeValue(startCode,length);
and this is the code
static int placeValue(int N, int num)
{
int total = 1, value = 0, rem = 0;
while (true) {
rem = N % 10;
N = N / 10;
if (rem == num) {
value = total * rem;
break;
}
total = total * 10;
}
return value;
}
so if i have 89765, i would want 80000,
but instead it return the place value of whatever length is.
So,
for 89765, the length would be 5, so the return value is 5 i.e. the value in the ones place.
but if the number was 85760
then it would return 5000.
I hope that makes sense.
Any suggestions would be much appreicated.
In my opinions, if I can avoid 'calculating' I will compute the answer from other concept since I am not confidence on my math (haha).
Here is my answer. (only work in positive numbers)
I think the length of the inputted number is not necessary.
static int placeValue2(int N) {
String tar = N+"";
String rtn = tar.substring(0,1); // take first digital
for (int i=0;i<tar.length()-1;i++) // pad following digitals
rtn+="0";
return Integer.parseInt(rtn);
}
I appreciate you asked the question here.
Here is my solution. I don't know why you are taking two parameters, but I tried it from one param.
class PlaceValue{
int placeValue(int num){
int length = 0; int temp2=1;
boolean result=false;
long temp1=1;
if (num<0){
result=true;
num=num*(-1);
}
if (num==0){
System.out.println("Value 0 not allowed");
return 0;
}
while (temp1 <= num){ //This loop checks for the length, multiplying temp1 with 10
//untill its <= number. length++ counts the length.
length++;
temp1*=10;
}
for (int i=1; i<length; i++){//this loop multiplies temp2 with 10 length number times.
// like if length 2 then 100. if 5 then 10000
temp2=temp2*10;
}
temp2=(num/temp2)*temp2;
/* Let's say number is 2345. This would divide it over 1000, giving us 2;
in the same line multiplying it with the temp2 which is same 1000 resulting 2000.
now 2345 became 2000;
*/
if (result==true){
temp2=temp2*(-1);
}
return temp2;
}
}
Here is the code above. You can try this. If you are dealing with the long numbers, go for long in function type as well as the variable being returned and in the main function. I hope you understand. otherwise, ask me.
Do you want something like this?
public static int roundDown(int number, int magnitude) {
int mag = (int) Math.pow(10, magnitude);
return (number / mag) * mag;
}
roundDown(53278,4) -> 50000
roundDown(46287,3) -> 46000
roundDown(65478,2) -> 65400
roundDown(43298,1) -> 43290
roundDown(43278,0) -> 43278
So the equivalent that will only use the most significant digit is:
public static int roundDown(int number) {
int zeros = (int) Math.log10(number);
int mag = (int) Math.pow(10, zeros);
return (number / mag) * mag;
}

How to calculate the number of zeros in binary?

Hi I am making a method that can take an integer as a parameter and compute how many zeros its binary form has. So for example, if I have binaryZeros(44), its binary form is 101100. Therefore, binaryZeros(44) should return 3. However, I am making some errors and I cannot tell where it is coming from. I would appreciate it if someone can point out where I am making that error, or if my approach (logic) to this problem is good enough. Thank you!
My code is Below:
public static int binaryZeros(int n) {
int zeroCount = 0;
double m = n;
while (m >= 0.0) {
m = m / 2.0;
if (m == Math.floor(m)) {
zeroCount++;
} else {
m = Math.floor(m);
}
}
return zeroCount;
}
Below is a more concise way to solve this problem
public static int binaryZeros(int n) {
int zeroCount = 0;
// Run a while loop until n is greater than or equals to 1
while(n >= 1)
{
/* Use modulo operator to get the reminder of division by 2 (reminder will be 1 or 0 as you are dividing by 2).
Keep in mind that binary representation is an array of these reminders until the number is equal to 1.
And once the number is equal to 1 the reminder is 1, so you can exit the loop there.*/
if(n % 2 == 0)
{
zeroCount++;
}
n = n / 2;
}
return zeroCount;
}
Your approach is good, but I think there's a better way to do it. The Integer class has a static method that returns the binary of a number: Integer.toBinaryString(num) . This will return a String.
Then, you can just check if there are any 0 in that string with method that has a for loop and evaluating with an if:
public int getZeros(String binaryString){
int zeros = 0;
for(int i=0; i < binaryString.length; i++)
if(binaryString.charAt[i].equals('0')
zeros++;
return zeros;
}
I believe this would be a simpler option and it doesn't have any errors.
Once m == 0.0, it will never change, so your while loop will never stop.
If you start with a number m >= 0, it can never become negative no matter how many times you divide it by 2 or use Math.floor. The loop should stop when m reaches 0, so change the condition to while (m > 0.0).
Note that you could do the same thing with built-in standard library methods. For example, there is a method that returns the number of leading zeros in a number, and a method that returns the number of bits set to 1. Using both you can compute the number of zeros that are not leading zeros:
static int binaryZeros(int n) {
return Integer.SIZE - Integer.numberOfLeadingZeros(n) - Integer.bitCount(n);
}
Here is one way. It simply complements the integer reversing 1's and 0's and then counts the 1 bits. You should not be using floating point math when doing this.
~ complements the bits
&1 masks the low order bit. Is either 1 or 0
>>> shifts right 1 bit including sign bit.
System.out.println(binaryZeros(44) + " (" +Integer.toBinaryString(44) +")");
System.out.println(binaryZeros(-44) + " ("Integer.toBinaryString(-44)+")");
public static int binaryZeros(int v) {
int count = 0;
while (v != 0) {
// count 1 bits
// of ~v
count += (~v)&1;
v >>>=1;
}
return count;
}
Prints
3 (101100)
4 (11111111111111111111111111010100)
Just be simple, whe there's Integer.bitCount(n) method:
public static int binaryZeros(int n) {
long val = n & 0xFFFFFFFFL;
int totalBits = (int)(Math.log(val) / Math.log(2) + 1);
int setBits = Long.bitCount(val);
return totalBits - setBits;
}
public static int getZeros(int num) {
String str= Integer.toBinaryString(num);
int count=0;
for(int i=0; i<str.length(); i++) {
if(str.charAt(i)=='0') count++;
}
return count;
}
The method toBinaryString() returns a string representation of the integer argument as an unsigned integer in base 2. It accepts an argument in Int data-type and returns the corresponding binary string.
Then the for loop counts the number of zeros in the String and returns it.

Java Compute C(n,k) and factorial with biginteger

I want to compute the answer of C(n,k),such as C(10,2)=10*9/2*1 = 45
If I test my code by small numbers like 10, the code works.
However, when I try to compute C(1000,900), it compiles
Exception in thread "main" java.lang.ArithmeticException: / by zero
I've seen someone says it should use BigInteger,But after I tried, it still has errors.
For example: I change int factorial into BigInteger factorial,
while the for loop in cSelect, I can not change int i into BigInteger type,
As result, the answer up/factorial(y) has errors.
Please help me to fix this problem. Thanks!!
public class Test {
// Write a factorial function
static int factorial(int m) {
int result =1;
for (int i=2; i<=m; i++) {
result = result*i;
}
return result;
}
// Caculate C(x,y)
static int cSelect(int x, int y) {
int up=1;
for(int i=x; i>=(x-y+1); i--) {
up = up*i;
}
return up/factorial(y);
}
public static void main(String[] args) {
System.out.println(cSelect(1000,900));
}
}
Your code is fairly easy to translate in factorial. Start with ONE, multiply by the BigInteger.valueOf(long) for each i in your loop. Like,
// Write a factorial function
static BigInteger factorial(int m) {
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= m; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
Your other function does exactly the same, plus a division by the result of factorial(y). Like,
// Caculate C(x,y)
static BigInteger cSelect(int x, int y) {
BigInteger up = BigInteger.ONE;
for (int i = x; i >= (x - y + 1); i--) {
up = up.multiply(BigInteger.valueOf(i));
}
return up.divide(factorial(y));
}
With no other changes I get
63850511926305130236698511142022274281262900693853331776286816221524376994750901948920974351797699894319420811933446197797592213357065053890
Which I assume is correct.
First, return value must be BigInteger, because result of C(1000,900) far exceeds the range on an int.
Second, you don't need separate factorial() method. Doing the division as you iterate will improve memory footprint by not creating excessively large intermediate values (at cost of doing multiple divisions, but even so it might actually be faster).
Like this:
static BigInteger cSelect(int x, int y) {
BigInteger v = BigInteger.ONE;
for (int i = x, j = 1; j <= y; i--, j++)
v = v.multiply(BigInteger.valueOf(i)).divide(BigInteger.valueOf(j));
return v;
}
By counting i down and j up, there will never be a fraction from the division.
Test
System.out.println(cSelect(10, 2));
System.out.println(cSelect(1000, 900));
Output
45
63850511926305130236698511142022274281262900693853331776286816221524376994750901948920974351797699894319420811933446197797592213357065053890
You have to use BigInteger to do the calculation.
The value you are trying to compute is approximately 6.385051192630516e+139 and it is not representable as a Java primitive integer value.
Even if the result was representable, the reason you are getting divide by zero errors is that the divisor expression 900! ∗ 100! is overflowing to zero. You then divide by that zero.
The reason that it overflows to zero is that it is divisible by 2^32 and 2^64. That can be proven by using some simple algebra to compute the number of factors of 2 there are in 900! and 100!

Trailing Zeroes of a Factorial

I'm trying to solve this coding question:
Given an integer n, return the number of trailing zeroes in n!
Below is my code (codec this up using the wiki link)
public int trailingZeroes(int n) {
int count = 0, i = 5;
while(i<=n){
count+= n/i;
i*=5;
}
return count;
}
This runs for all test cases except when n = Integer.MAX_VALUE upon which I get a TLE. How can I fix this code to make it cover that test case. I have read about five articles on the net and everything seems to agree with my approach.
Much thanks.
So, I followed the long/BigInteger approach (thanks y'all):
public int trailingZeroes(int n) {
long count = 0;
for(long i= 5; n/i >= 1; i= i*5){
count+= n/i;
}
return (int)count;
}
As Iaune observed, your loop will never terminate when n is Integer.MAX_VALUE, because there is no int greater than that number (by definition). You should be able to restructure your loop to avoid that problem. For instance, this is the same basic approach, but flipped upside-down:
public int trailingZeroes(int n) {
int count = 0;
while (n > 0) {
n /= 5;
count += n;
}
return count;
}
You cannot write a for or while loop where the loop counter is an int and the upper limit is <= Integer.MAX_VALUE.
What happens with a simple increment (counter++) is that the loop counter is set to that value, the body executes and then the counter is incremented which results in a negative number, Integer.MIN_VALUE. And then everything happens all over again.
Other weird things may happen when the loop counter is incremented in quantities > 1 or (as here) is multiplied: the int loop counter just can't hold a value > Integer.MAX_VALUE
Consider another approach for iterating over these numbers. Or handle MAX_VALUE separately.
Your problem is that once i gets large enough (more than Integer.MAX_INT / 5) then the line i*=5; causes i to overflow to the "wrong" value. The value in question is 5 to the 14th power, which is 6103515625, but which overflows to 1808548329.
The result of this is that the loop just keeps executing forever. i will never become a value that's not <= Integer.MAX_INT, because there's just no such int.
To avoid this, you need i to be a larger data type than an int. If you change i and count in your original code to long, this will work fine. Of course, BigInteger would also work.
public class FactorialNumberTrailingZeros {
public static void main(String[] args) {
System.out.println(trailingZeroes(1000020));
}
private static int trailingZeroes(int n) {
int count = 0;
while (n > 0 && (n % 10 == 0)) {
n /= 10;
count ++;
}
return count;
}
}
public static void main(String[] args) {
int result = findFactorialTrailingZero(100);
System.out.println("no of trailing zeros are " + result);
}
public static int findFactorialTrailingZero(int no) {
int zeros = no / 5;
int zeroIncrementNo = 25;
int zerosIncrementFactor = 1;
int nextZeroIncrenent = 5;
for (int i = 1;no >= zeroIncrementNo; i++) {
zeros=zeros+zerosIncrementFactor;
zeroIncrementNo=25*(i+1);
if(i+1==nextZeroIncrenent){
zerosIncrementFactor++;
nextZeroIncrenent=nextZeroIncrenent*5;
}
}
return zeros;
/*
[n/5]+[n/25]+[n/125]+....
if n<25 then [n/5]
if n<125 then [n/5]+[n/25]
if n<625 then [n/5]+[n/25]+[n/125]
*/
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int countTrailingZeroes(int n)
{
int res=0;
for(int i=5;i<=n;i=i*5){
res=res+n/i;
}
return res;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n;
cin>>n;
cout<<countTrailingZeroes(n);
return 0;
}
Output
25
6
Explanation:
25!=1.551121e+25 i.e contains 6 trailing zeroes
Here is my python code that could solve your problem:
def check(n):
j,ans=5,0
while j<=n:
ans=ans+n//j
j=j*5
return ans

Remove digits from a number in Java [closed]

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 do I remove the first digit of an integer?
My input is an integer (for example i = 123456789).
I then want to remove the first digit, so that i equals 23456789.
try this
n = n % (int) Math.pow(10, (int) Math.log10(n));
Here is one way to do it:
Convert it to String
Take the substring without the first "digit"
Convert it to int
Code:
public static void main(String[] args)
{
int x = 123456789;
String x_str = Integer.toString(x);
int new_x = Integer.parseInt(x_str.substring(1));
System.out.println(new_x);
}
Output:
23456789
Note: This can be done in one line with
int x = 123456789;
int new_x = Integer.parseInt(Integer.toString(x).substring(1));
Edit:
To handle negative-case, check if number is positive or integer:
int new_x = Integer.parseInt(x > 0 ?
Integer.toString(x).substring(1) : Integer.toString(x).substring(2));
If you want to avoid the string conversion, you can find the high digit and subtract it.
public static void main(String[] args) {
int x = 123456789;
System.out.println("x = " + x);
int hi = x, n = 0;
while (hi > 9) {
hi /= 10;
++n;
}
for (int i = 0; i < n; i++) hi *= 10;
x -= hi;
System.out.println("x with high digit removed = " + x);
}
Here's the one-line, purely numeric solution:
i %= (int) Math.pow(10, (int) Math.log10(i));
Alternate approach:
int stripLeading(int i) {
if(i > 0) {
return i - (int)Math.pow(10, (int)Math.log10(i));
} else if(i > 0) {
return i + (int)Math.pow(10, (int)Math.log(-i+1));
} else {
return 0;
}
}
I think I remember the string-free version of this … although I totally agree with #Christian as how I would do it…
NOTE: as #Darren Gilroy pointed out, one must consider negatives and zero spocially, and my function fails to do so.
Of course % is a better solution also.
public static void main (String [] argv)
{
final int x = 123456789;
int newX = x;
/* How many digits are there? */
final double originalLog = Math.floor (Math.log10 (x));
/* Let's subtract 10 to that power until the number is smaller */
final int getRidOf = (int)Math.pow (10, originalLog);
while (originalLog == Math.floor (Math.log10 (newX)))
{ newX -= getRidOf; }
System.out.println (newX);
}
Poor profiling attempt:
Looping the above function without the println for 20,000,000,000 repeats in a for loop:
real 0m9.943s
user 0m9.890s
sys 0m0.028s
The same with Christian's far-easier-to-understand and perfectly functionable version, but for only 200,000,000 repeats (because I'm lazy and got tired of waiting):
real 0m18.581s
user 0m17.972s
sys 0m0.574s
So one might argue that constructing the String objects is probably slowing it down by roughly 200×, but that isn't a really finely-tuned profiling set-up.
If you want to go for simpler methods and without using String, then here's my simple take:
Count number of digits int the integer.
Divide the int by 10^n. n is the number of digits.
Obtain absolute value of the result. //In case of (-)ve numbers.
For example
int i = 123456789;
int n = getDigitCount(i);
int r = Math.abs(i / (int)Math.pow(10,n)); //r stores result.
And you'd require this method:
int getDigitCount(int num)
{
int c = 0;
while(num > 0){
num/=10;
c++;
}
return c;
}

Categories

Resources