This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Need help in mod 1000000007 questions
I have a set of numbers for which i want to compute total product modulo 1000007. e.g if my array contains 1000 numbers then i need to compute the following.
int product = 1;
for(int i=0;i<Array_Max;i++)
product = product * Array[i]
then product modulo 1000007 = ?
Is there any algorithm to optimize the above pseudo code ? Right now i am unable to store the product because of overflow.
Any suggestion appreciated.
Use longs for the product - this will be enough to hold the result of multiplying two integers.
You also will want to compute the modulo on each iteration so that you avoid overflow (this is safe to do from a mathematical perspective, as it doesn't change the result modulo 1000007 at the end).
You could also use BigIntegers if you wanted, but it would be much slower.
Related
There is a very famous and simple problem on hacker-rank that goes as follows:
Given five positive integers, find the minimum and maximum values that can be calculated by summing exactly four of the five integers. Then print the respective minimum and maximum values as a single line of two space-separated long integers.
Example arr = [1,3,5,7,9]
The minimum sum is 1+3+5+7=16 and the maximum sum is 3+5+7+9=24.
Now, i solved this problem as follows:
long max = Collections.max(intList);
long min = Collections.min(intList);
long sum = intList.stream().mapToInt(Integer::intValue).sum();
System.out.println((sum-max)+" "+(sum-min));
It works, but is falling short of 3 test cases. Any suggestions, or improvements that can be done? I am trying to improve my programming skills and this is something that i dont want to let go till i completely understand.
Thanks!
EDIT
Here is the improved code and the answer to anyone who is looking :
long max = Collections.max(arr);
long min = Collections.min(arr);
long sum = arr.stream().mapToLong(Integer::longValue).sum();
System.out.println((sum-max)+" "+(sum-min));
The only problem I see is that you are expected to calculate long result, but are calculating intermediary values (e.g. total sum) in int. This can result in type overflow.
Basically substitute mapToInt with mapToLong and use rather longValue.
PS: Otherwise I like your solution in the sense it is concise and utilizes APIs well. If you are after pixel perfect performance you might want to spare unnecessary cycles over the list, but this is really extreme optimization (as your solution is also linear in complexity) and I doubt it will ever make a difference.
This question already has answers here:
What is a plain English explanation of "Big O" notation?
(43 answers)
Closed 4 years ago.
Why do we just take the highest degree of polynomial for Big Oh notation. I understand that we can drop the constants as they won't matter for a very high value of 'n'.
But, say an algorithm takes (nlogn + n) time, then why do we ignore 'n' in this case. And the big Oh comes out to be O(nlogn).
Big Oh has to be the upper bound of time taken by the algorithm. So, shouldn't it be (nlogn + n), even for very high values of n?
Because O is asymptotic comparison which answers the question how the function compare for large n. Lower degrees of polynomial become insignificant for function behavior once n is sufficiently large.
One way to see that is: "nlog(n) + n" is smaller than "2nlog(n)". Now you can drop the 2.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The sum to infinity of the following series is to be found:
1 1/2 1/3 1/4 1/5 ...
According to the explanation of a certain scientist, infinity is that point beyond which any point is non existent, i.e., inf + x = inf or inf ~ (inf + x) = 0. So, based on this theory, the following algorithm was used:
float sum=0.0;
for(int i=0;;i++){
if((sum+(1.0/i))==sum)
break;
sum+=(1.0/i);
}
/* print the value of sum */
The algorithm was run in C and JAVA and both gave the output as inf. The print statements written in C and Java respectively are
printf("%6f",sum);
System.out.println(sum);
EDIT:
The code written earlier (in the question) had a mistake because I typed it, didn't copy-paste. Sorry for that. That being solved, here's the code I'd base my question upon:
float sum=0.0;
for(int i=1;;i++){
if((sum+ (1.0/i))==sum)
break;
sum+=(1.0/i);
}
/*print the value of sum*/
A friend of mine said he got the output as a finite fractional number in C. But in my case, the program never terminated, both in C and Java(This output was got from the new edited code posted above. Do not consider the previous faulty code and it's output which was "INF".) My question is, is this algorithm acceptable? And if yes, then I'd like to know the possible of cause different outputs in C. Thanks.
The algorithm was run in C and JAVA and both gave the output as inf.
That is because there is a bug in your code. You are starting with i == 0. When you calculate 1.0 / 0 you get an INF.
The series is supposed to start with i == 1 ...
You edited the question to fix to that particular bug.
Even so, you still will never get a correct value for the sum to infinity. The series diverges (goes to infinity) but given the way you are calculating it, there is no way that you will get there.
Eventually, you will reach a point where 1.0/i is too small to change sum and you will break out of the loop. I expect that will happen before i == Integer.MAX_VALUE ... but if it didn't, then you would run into ANOTHER bug in your code. If i ever reached Integer.MAX_VALUE then it would wrap around to Integer.MIN_VALUE and you will start adding negative terms to the sum. Oops!
Actually, what you are trying to calculate is the Harmonic Series. The partial sums (for N terms) converge to loge N + E, where E is the Euler–Mascheroni constant.
Source: https://en.wikipedia.org/wiki/Harmonic_series_%28mathematics%29#Partial_sums
From this, one should be able to estimate when the difference between Nth partial sum and 1.0 / N becomes large enough to stop the iteration.
A final note: you will get more accurate sums if you sum in the opposite direction; i.e. starting with very large N and summing with N reducing to 1.
There are many problems with your code. Your program doesn't work, it only seems to work.
Never compare float numbers for equality.
Computers can't divide by zero.
Literals 0.0 are of type double. Meaning that the calculation sum+(1.0/i) is performed on type double, which might be a larger type than float on the particular system. Your code assumes that float and double have the same representation, so it is non-portable.
Therefore the result may not be too large during the calculation, which is done on type double, but it doesn't fit when you try to show it back into a float. Instead use f prefix on all literals, that is: 1.0f. Or just use double consistently all over the program.
Avoid cryptic loops. There's no need to move the loop condition inside the loop body. Your loop should look something like for(int i=0; float_compare(sum+1.0f/i, sum); i++), where float_compare is some way to compare float numbers. Something like this:
#include <math.h>
#define EPSILON 0.00001f
inline bool float_compare (float x, float y)
{
return fabsf(result - expectedResult) < EPSILON;
}
Some notes The range of i is important - integers have only fixed representations.
The series 1/1 + 1/2 + 1/3 + 1/4 ... is divergent (wikipedia : sum of recipricals)
The range of an int wraps, and so you would also be adding -1/1 -1/2 ... which would tend to 0.
The series progresses to infinity very slowly, so a computer may not be the best way of working it out.
So I am making an application that can solve problems with Empirical Formulae and I need some code that would do something like:
If numbers are 2.5, 1, 3 it should change them to 2.5*2 = 5, 1*2 = 2, 3*2 = 6 so that the number with the decimal is converted to a whole number and the other numbers are adjusted appropriately.
I thought of this logic:
for(n = 1; (Math.round(simplestRat[0]) * n) != (int)SimplestRat[0]; n++)
to increment a counter that would multiply an integer to do what I want it to but I am skeptical about this code even at this phase and do not think it will work.
It would be a lot of help if someone could suggest a code for this or improve upon this code or even give me a link to another post for this problem as I was unable to find anything regarding this type of problem.
Any help is appreciated. Thanks
Okay, so you have to have a few steps. First, get them all into whole numbers. The easiest way is to find an appropriate power of ten to multiply them all by that leaves them as integers. This is a useful check: How to test if a double is an integer.
Then cast them to integers, and start working through them looking for common prime factors. This'll be a process similar to Eratosthenes' Sieve (http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) but with division at the end. For each prime, see if all 3 numbers divide by it exactly (modulo prime == 0). If they do, divide and reset the primes to 2. If they don't, next prime.
This should give you the lowest common ratio between the numbers. Any additional multiplier that came from the original stage is shaved off by the common primes method.
This question already has answers here:
Computational complexity of Fibonacci Sequence
(12 answers)
Closed 6 years ago.
So, i've got a recursive method in Java for getting the 'n'th fibonacci number - The only question i have, is: what's the time complexity? I think it's O(2^n), but i may be mistaken? (I know that iterative is way better, but it's an exercise)
public int fibonacciRecursive(int n)
{
if(n == 1 || n == 2) return 1;
else return fibonacciRecursive(n-2) + fibonacciRecursive(n-1);
}
Your recursive code has exponential runtime. But I don't think the base is 2, but probably the golden ratio (about 1.62). But of course O(1.62^n) is automatically O(2^n) too.
The runtime can be calculated recursively:
t(1)=1
t(2)=1
t(n)=t(n-1)+t(n-2)+1
This is very similar to the recursive definition of the fibonacci numbers themselves. The +1 in the recursive equation is probably irrelevant for large n. S I believe that it grows approximately as fast as the fibo numbers, and those grow exponentially with the golden ratio as base.
You can speed it up using memoization, i.e. caching already calculated results. Then it has O(n) runtime just like the iterative version.
Your iterative code has a runtime of O(n)
You have a simple loop with O(n) steps and constant time for each iteration.
You can use this
to calculate Fn in O(log n)
Each function call does exactly one addition, or returns 1. The base cases only return the value one, so the total number of additions is fib(n)-1. The total number of function calls is therefore 2*fib(n)-1, so the time complexity is Θ(fib(N)) = Θ(phi^N), which is bounded by O(2^N).
O(2^n)? I see only O(n) here.
I wonder why you'd continue to calculate and re-calculate these? Wouldn't caching the ones you have be a good idea, as long as the memory requirements didn't become too odious?
Since they aren't changing, I'd generate a table and do lookups if speed mattered to me.
It's easy to see (and to prove by induction) that the total number of calls to fibonacciRecursive is exactly equal to the final value returned. That is indeed exponential in the input number.