For-loop returning wrong results - java

I am getting wrong results resolving below task:
Generalized harmonic numbers. Write a program GeneralizedHarmonic.java that takes two integer command-line arguments n and r and uses a for loop to compute the nth generalized harmonic number of order r, which is defined by the following formula:
formula
public class GeneralizedHarmonic {
public static void main(String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int i;
double sum = 0;
for (i = 0; i <= a; i++) {
sum += 1 / Math.pow(i, b);
}
System.out.println(sum);
}
}
This is my code but I could not get the correct test output.The output result is always Infinity.
test outputs

You have initliazed int i = 0 in for-loop for (i = 0; i <= a; i++) and so the first element of your harmonic number isn't , but .
The code that works:
public class GeneralizedHarmonic {
public static void main(String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
double sum = 0;
for (int i = 1; i <= a; i++) {
sum += 1 / Math.pow(i, b);
}
System.out.println(sum);
}
}

Related

I want to give out only one Argument instead of all 4

I want that the user can type four arguments, and this results that the numbers which the user typed in get summed up together. But now I have the Problem, if the user wants to give out less arguments. How do I sum up that?
public class Sum {
public static void main(String[] args) {
int q = Integer.parseInt(args[0]);
int w = Integer.parseInt(args[1]);
int e = Integer.parseInt(args[2]);
int r = Integer.parseInt(args[3]);
int summe = q + w + e + r;
System.out.println(summe);
You have to check the number of input arguments (i.e. args.length) in order not to try accessing invalid indices of the args arrays.
You don't need all of these variables if you only want to compute the sum:
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < args.length; i++) {
sum += Integer.parseInt (args[i]);
}
System.out.println(sum);
}

How to find the sum of factorial of all numbers in a series?

I want to create a program to find the sum of factorial of all numbers in a series till 20.
I have to find 's' in s = 1 + (1*2) + (1*2*3) + ...(1*2*3...20).
I tried a program but it is not working. I am using BlueJ IDE.
int a =1;
int s = 0;
for(int i = 1; i <= 10; i++)
{
while (i >0)
{
a = a * i;
i--;
}
s = s+a;
}
System.out.println(s);
The compiler does not show any error message but when I run the program the JVM(Java Virtual Machine) keeps loading and the output screen does not show up.
You can try this one :
public class Main
{
public static void main (String[]args)
{
int fact = 1;
int sum = 0;
int i, j = 1;
for (i = 1; i <= 20; i++)
{
for (j = 1; j <= i; j++)
{
fact = fact * j;
}
sum += fact;
System.out.println ("sum = " + sum);
fact = 1;
}
}
}
Always give proper variable name and Try to avoid to use same variable at different places i.e you have use variable i in outer and inner loop which is not good habit.
You should be using a different loop variable name in your inner loop, and you also need to use a long to store your sum. In fact, I would first write a method to multiply up to a number in the series. Like,
static long multiplyTo(int n) {
long r = 1L;
for (int i = 2; i <= n; i++) {
r *= i;
}
return r;
}
Then you can invoke that and calculate your sum with a simple loop. Like,
long sum = 0L;
for (int i = 1; i <= 20; i++) {
sum += multiplyTo(i);
}
System.out.println(sum);
I get
2561327494111820313
Using streams:
long s = LongStream.rangeClosed(1, 20)
.map(upper -> LongStream.rangeClosed(1, upper)
.reduce(1, (a, b) -> a * b))
.sum();
System.out.println(s);
Prints 2561327494111820313
I did the same program using Scanner Class
import java.util.*;
class Sum_Factorial
{
public static void main()
{
Scanner in = new Scanner(System.in);
int i; //Denotes Integer
int n; //Denotes Number
int f=1; //Denotes Factorial
int s=0; //Denotes Sum
System.out.println("Enter the value of N : ");
n=in.nextInt();
for(i=1; i<=n; i++)
{
f=f*i;
s=s+f;
}
System.out.println("Sum of the factorial numbers is "+s);
}
}

Erroneous behaviour of Java 8 Stream.sum()

Today while solving this question on HackerRank I used Array stream .sum() function to sum all the entries and proceeded with my algorithm. But for sum reason I found that my algorithm fails for some cases. I used diff to find out it passes 99% cases and for 1% the output is nearly equal but is less than the original answer. That's why I replaced the stream .sum() with a for loop and unexpectedly it passed all the test cases. I tried but couldn't ascertain this uncertain behaviour.
My implementation using stream.sum() :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
for (int j = 0; j < number; j++) h[j] = in.nextInt();
System.out.println(new MandragoraForestSolver().solve(h));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long sum = Arrays.stream(h)
.sum();
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Implementation without Java stream :
public class MandragoraForest {
public static void main(String[] args) {
InputReader in = new InputReader(System.in);
for (int i = in.nextInt(); i > 0; i--) {
int number = in.nextInt();
int[] h = new int[number];
long sum = 0;
for (int j = 0; j < number; j++) {
h[j] = in.nextInt();
sum += h[j];
}
System.out.println(new MandragoraForestSolver().solve(h, sum));
}
}
}
class MandragoraForestSolver {
public long solve(int[] h, long sum) {
if (h.length==1) return h[0];
Arrays.parallelSort(h);
long ans = -1;
for (long i=0, strength = 2; i<h.length; i++, strength++) {
sum -= h[(int)i];
ans = Math.max(ans, strength * sum);
}
return ans;
}
}
Is there something that I'am missing out ? What could be the reason for this behaviour?
There is one significant difference between using a stream and a loop - the possibility of arithmetic overflow.
Arrays.stream(int[]) returns an IntStream, whose sum() method returns an int result. If the sum exceeds Integer.MAX_VALUE, a silent integer overflow will occur.
However your loop sums by adding int values to a long total, which would not suffer from arithmetic overflow.
The sum of integers in one of the tests must exceed Integer.MAX_VALUE, testing that a long is used to (correctly) calculate the total.
If you want to use a stream to sum, you need to convert the IntStream to a LongStream, which you can do like this:
long sum = Arrays.stream(big).asLongStream().sum();

LCM (lowest common multiple) in Java

I need help with this loop. One of my course assignments is to make a LCM program.
Sample output:
(8,12) LCM is 24
(4,3) LCM is 12
(5,10,20) LCM is 20
(18,24,52) LCM is 936
(12,10,26) LCM is 780
(99,63,24) LCM is 5544
(62,16,24) LCM is 1488
I have this so far for 2 numbers but I'm not sure how to do 3 numbers. We're supposed to use methods on other classes so this is what I have for the LCM class.
public class LCM {
private int n, x, s = 1, t = 1;
public LCM()
{
n = 0;
x = 0;
s = 1;
t = 1;
}
public int lcmFind(int i, int y) {
for (n = 1;; n++) {
s = i * n;
for (x = 1; t < s; x++) {
t = y * x;
}
if (s == t)
break;
}
return (s);
}
}
If you want to get LCM of 3+ numbers you can use your method lcmFind in following way:
int a = 2;
int b = 3;
int c = 5;
LCM l = new LCM();
int lcm = l.lcmFind(l.lcmFind(a, b), c);
Reccomendations:
Make n,x, s and t variables local in lcmFind. Because you need them ONLY in lcmFind method and you need to reset their values in every invocation of lcmFind.
Make your lcmFind method static. You don't need to instantiate new object in order to calc lcm. This way you can use it like LCM.lcmFind(3,4), or even better rename method and use something like LCM.find(3,4).
EDIT
If you need to make method that takes variable number of argument you should check varargs. So you'll get something like:
public int lcmFind(int.. args) {
// args is actually array of ints.
// calculate lcm of all values in array.
// usage: lcmFind(1,4) or lcmFind(1,5,6,3)
}
You can use your first version of lcmFind that takes 2 arguments and calculate lcm of many values using it.
EDIT 2
If you need only 2 and 3-args version of lcmFind than you can just add 3-arg version:
public int lcmFind(int a, int b, int c) {
return lcmFind(lcmFind(a, b), c);
}
I found this link and I guess this is most simple and clean solution:
/**
* Calculate Lowest Common Multiplier
*/
public static int LCM(int a, int b) {
return (a * b) / GCF(a, b);
}
/**
* Calculate Greatest Common Factor
*/
public static int GCF(int a, int b) {
if (b == 0) {
return a;
} else {
return (GCF(b, a % b));
}
}
try
public int lcm(int... a) {
for (int m = 1;; m++) {
int n = a.length;
for (int i : a) {
if (m % i != 0) {
break;
}
if (--n == 0) {
return m;
}
}
}
}
public static int gcd(int a, int b){
return (b == 0) ? a : gcd(b, a % b);
}
public static int gcd(int... args){
int r = args[0];
int i = 0;
while(i < args.length - 1)
r = gcd(r,args[++i]);
return r;
}
public static int lcm(int a, int b){
return a * b / gcd(a,b);
}
public static int lcm(int... args){
int r = args[0];
int i = 0;
while(i < args.length - 1)
r = lcm(r,args[++i]);
return r;
}
static int getLCM(int a,int b)
{
int x;
int y;
if(a<b)
{
x=a;
y=b;
}
else
{
x=b;
y=a;
}
int i=1;
while(true)
{
int x1=x*i;
int y1=y*i;
for(int j=1;j<=i;j++)
{
if(x1==y*j)
{
return x1;
}
}
i++;
}
}
I think you have the answer already, since it's an old post. still posting my answer. Below is the code to find the LCM for an array:
import java.util.Arrays;
import java.util.Scanner;
public class ArrayEqualAmz {
static int lcm =1;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int [] arr = new int[n];
for(int i=0; i<n; i++){
arr[i] = sc.nextInt();
}
System.out.println("lcm = "+lcm(arr));
}
// find the factor
public static int divisor(int x[]){
Arrays.sort(x);
int num=0;
for(int i=x.length-1; i>=0; i--){
if(x[i] != 1 )
num=x[i];
}
for(int j=2; j<=num; j++){
if(num%j==0){
return j;}
}
return num;
}
//finding the lcm
public static int lcm(int arr[]){
while(true){
int j = divisor(arr);
if(j==0){break;}
lcm = lcm*j;
for(int i=0; i<arr.length; i++){
if(arr[i]%j==0){
arr[i] = arr[i]/j;}
System.out.print(arr[i]+",");
}
System.out.println( " factor= "+lcm);
return lcm(arr);
}
return lcm;
}
}
Try this
int n1 = 72, n2 = 120, lcm;
// maximum number between n1 and n2 is stored in lcm
lcm = (n1 > n2) ? n1 : n2;
// Always true
while(true)
{
if( lcm % n1 == 0 && lcm % n2 == 0 )
{
System.out.printf("The LCM of %d and %d is %d.", n1, n2, lcm);
break;
}
++lcm;
}
You can re use the same function written for lcm of two numbers. Just pass one of the arguments as follows:
The function code can be like this:
public static int lcm(int num1,int num2) {
boolean flag = false;
int lcm = 0;
for(int i= 1;!flag; i++){
flag = (num1 < num2)?(num2*i)%num1==0:(num1*i)%num2==0;
lcm = num1<num2?num2*i:num1*i;
}
return lcm;
}
Call the function like this:
public static void main(String[] args) {
System.out.println("lcm "+lcm(lcm(20,80),40));
}

Find factorial of large numbers in Java

I tried to find the factorial of a large number e.g. 8785856 in a typical way using for-loop and double data type.
But it is displaying infinity as the result, may be because it is exceeding its limit.
So please guide me the way to find the factorial of a very large number.
My code:
class abc
{
public static void main (String[]args)
{
double fact=1;
for(int i=1;i<=8785856;i++)
{
fact=fact*i;
}
System.out.println(fact);
}
}
Output:-
Infinity
I am new to Java but have learned some concepts of IO-handling and all.
public static void main(String[] args) {
BigInteger fact = BigInteger.valueOf(1);
for (int i = 1; i <= 8785856; i++)
fact = fact.multiply(BigInteger.valueOf(i));
System.out.println(fact);
}
You might want to reconsider calculating this huge value. Wolfram Alpha's Approximation suggests it will most certainly not fit in your main memory to be displayed.
This code should work fine :-
public class BigMath {
public static String factorial(int n) {
return factorial(n, 300);
}
private static String factorial(int n, int maxSize) {
int res[] = new int[maxSize];
res[0] = 1; // Initialize result
int res_size = 1;
// Apply simple factorial formula n! = 1 * 2 * 3 * 4... * n
for (int x = 2; x <= n; x++) {
res_size = multiply(x, res, res_size);
}
StringBuffer buff = new StringBuffer();
for (int i = res_size - 1; i >= 0; i--) {
buff.append(res[i]);
}
return buff.toString();
}
/**
* This function multiplies x with the number represented by res[]. res_size
* is size of res[] or number of digits in the number represented by res[].
* This function uses simple school mathematics for multiplication.
*
* This function may value of res_size and returns the new value of res_size.
*/
private static int multiply(int x, int res[], int res_size) {
int carry = 0; // Initialize carry.
// One by one multiply n with individual digits of res[].
for (int i = 0; i < res_size; i++) {
int prod = res[i] * x + carry;
res[i] = prod % 10; // Store last digit of 'prod' in res[]
carry = prod / 10; // Put rest in carry
}
// Put carry in res and increase result size.
while (carry != 0) {
res[res_size] = carry % 10;
carry = carry / 10;
res_size++;
}
return res_size;
}
/** Driver method. */
public static void main(String[] args) {
int n = 100;
System.out.printf("Factorial %d = %s%n", n, factorial(n));
}
}
Hint: Use the BigInteger class, and be prepared to give the JVM a lot of memory. The value of 8785856! is a really big number.
Use the class BigInteger. ( I am not sure if that will even work for such huge integers )
Infinity is a special reserved value in the Double class used when you have exceed the maximum number the a double can hold.
If you want your code to work, use the BigDecimal class, but given the input number, don't expect your program to finish execution any time soon.
The above solutions for your problem (8785856!) using BigInteger would take literally hours of CPU time if not days. Do you need the exact result or would an approximation suffice?
There is a mathematical approach called "Sterling's Approximation
" which can be computed simply and fast, and the following is Gosper's improvement:
import java.util.*;
import java.math.*;
class main
{
public static void main(String args[])
{
Scanner sc= new Scanner(System.in);
int i;
int n=sc.nextInt();
BigInteger fact = BigInteger.valueOf(1);
for ( i = 1; i <= n; i++)
{
fact = fact.multiply(BigInteger.valueOf(i));
}
System.out.println(fact);
}
}
Try this:
import java.math.BigInteger;
public class LargeFactorial
{
public static void main(String[] args)
{
int n = 50;
}
public static BigInteger factorial(int n)
{
BigInteger result = BigInteger.ONE;
for (int i = 1; i <= n; i++)
result = result.multiply(new BigInteger(i + ""));
return result;
}
}
Scanner r = new Scanner(System.in);
System.out.print("Input Number : ");
int num = r.nextInt();
int ans = 1;
if (num <= 0) {
ans = 0;
}
while (num > 0) {
System.out.println(num + " x ");
ans *= num--;
}
System.out.println("\b\b=" + ans);
public static void main (String[] args) throws java.lang.Exception
{
BigInteger fact= BigInteger.ONE;
int factorialNo = 8785856 ;
for (int i = 2; i <= factorialNo; i++) {
fact = fact.multiply(new BigInteger(String.valueOf(i)));
}
System.out.println("Factorial of the given number is = " + fact);
}
import java.util.Scanner;
public class factorial {
public static void main(String[] args) {
System.out.println("Enter the number : ");
Scanner s=new Scanner(System.in);
int n=s.nextInt();
factorial f=new factorial();
int result=f.fact(n);
System.out.println("factorial of "+n+" is "+result);
}
int fact(int a)
{
if(a==1)
return 1;
else
return a*fact(a-1);
}
}

Categories

Resources