std::map seems to find elements which are not there - c++

So I've tried to create a simple program to calculate n-th fibonacci number mod 10^9+7 using the doubling formula with F[0]=0 and F[1]=1. and the program seems to work on my computer with compilers VS2010 and CodeBlocks with MinGW however testing my program on ideone returns 0 for every input. It seems that after the first iteration F.find(n) actually finds elements which shouldn't exist. Here's my code (in VS2010 I just changed the includes).
#include <bits/stdc++.h>
using namespace std;
std::map<unsigned long long,unsigned long long> F;
unsigned long long fib(unsigned long long n)
{
if(n==-1) return 0; // Shifting index by 1
if(n==0) return 1;
if(n==1) return 1;
if(F.find(n) != F.end()) return F[n]; // This seems to be the problem,
else
{
if(n%2==0) //
{
F[n/2-1] = fib(n/2-1)%1000000007;
F[n/2] = fib(n/2)%1000000007;
return F[n] = (F[n/2-1]*F[n/2-1]+F[n/2]*F[n/2])%1000000007;
}
else
{
F[n/2] = fib(n/2)%1000000007;
F[n/2+1] = fib(n/2+1)%1000000007;
return F[n] = (F[n/2]*(2*F[n/2+1]-F[n/2]))%1000000007;
}
}
}
int main() {
unsigned long long int broj;
cin >> broj; // input the number
cout << fib(broj-1) << endl;
return 0;
}

You have issue with expressions like this:
F[n/2-1] = fib(n/2-1)%1000000007;
as order of evaluation of operator[] on std::map is not defined it may call it before fib(n/2-1) and create an empty element there. You should store cached value in function where you calculate it.
Also calling std::map::operator[] with the same key as you used with std::map::find is wasteful.
Possible fix:
auto p = F.emplace( n, 0 );
if( p.second ) {
// element was not there
// calculate and store at p.first->second
}
return p.first->second;

Another possible fix is to add two temp variables lets say
unsigned long long a,b; and change the lines
F[n/2-1] = fib(n/2-1)%1000000007;
F[n/2] = fib(n/2)%1000000007;
To
a = fib(n/2-1)%1000000007;
b = fib(n/2)%1000000007;
F[n/2-1] = a;
F[n/2] = b;
This way it doesn't matter whether map creates the element then assign value. It also can optimize the following line
return F[n] = (F[n/2-1]*F[n/2-1]+F[n/2]*F[n/2])%1000000007;
To avoid searching for F[n/2-1] and F[n/2] into
return F[n] = (a*a+b*b)%1000000007;

Related

Last Digit of the Sum of Fibonacci Numbers. Unable to get exact answer

#include<iostream>
#include<vector>
#include<cstdlib>
#include <cassert>
using namespace std;
long long int LastDigitofSumofFibonacci(int n){long long int first=0;
long long int second=1;
long long int fibOfn;
long long int sum=1;
vector<long long int> V;
V.push_back(first);
V.push_back(second);
if(n==0) return first;
else if(n==1) return second;
else{
for(int i=2;i<60;i++){
fibOfn=first+second;
first=second;
second=fibOfn;
sum=sum+fibOfn;
//cout<<"i "<<i<<" fibOfn "<<fibOfn<<" fibOfnlastdigit "<<fibOfnlastdigit<<" first "<<first<<" second "<<second<<" sum "<<sum;
//cout<<endl;
sum=sum%10;
V.push_back(sum);
}
}
//for(auto element:V)
//cout<<element<<" ";
//cout<<endl;
//cout<<(n)%60<<endl;
return V[(n)%60];
}
int main(){
int n;
cin>>n;
long long int Base=LastDigitofSumofFibonacci(n);
cout<<Base<<endl;
}
In this I am trying to calculate the the last digit of Fibonacci series. I know and also read from net that last digit follow pattern of 60(0-59). from that concept wise I think my code is OK. but still I am unable to get the correct answers for large digit number.
I cleaned up the code a bit and fixed the issue with second not being computed % 10.
Since only the last digit is relevant all variables can be just int, no need for long long int to store a single digit. It would actually save ram to use uint8_t as type for the cache, but 60 bytes or 240 bytes isn't going to make a difference here.
The result repeats every 60 steps, which is the basis for the algorithm. But why compute this every time the function gets called? So lets make a static array so the computation only happens once. Lets go one step further with constinit and compute it at compile time.
As last change I made the argument to LastDigitofSumofFibonacci unsigned int. Unless you want to extend the fibonacci series backwards into the negative and extend the algorithm. unsigned int generates better code for n % 60.
#include <iostream>
#include <array>
int LastDigitofSumofFibonacci(unsigned int n) {
// The last digit of `fib(n)` and their sum repeats every 60 steps.
// https://en.wikipedia.org/wiki/Pisano_period
// Compute the first 60 values as lookup table at compile time.
static constinit std::array<int, 60> cache = []() {
int first = 0, second = 1;
std::array<int, 60> a{0, 1};
for (int i = 2; i < 60; i++) {
int t = first + second;
first = second;
second = t % 10;
a[i] = (a[i - 1] + t) % 10;
}
return a;
}();
// and now just look up the answer at run time.
return cache[n % 60];
}
int main(){
int n;
std::cin >> n;
std::cout << LastDigitofSumofFibonacci(n) << std::endl;
}
Somehow the code got a lot shorter just from eliminating some overhead here and there.

How to control implicit conversion from long to int?

I am working on this LeetCode problem to take an integer and reverse it, given that the reversed in is within the signed 32-bit range, in which case we should return 0.
and this code is doing just that, even with numbers like 1534236469/-1534236469. Except when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
I know this is not the cleanest code, but can you help me recognise what I'm missing?
#include<iostream>
#include<limits>
using namespace std;
class Solution {
public:
int reverse(int x) {
int a, r, y;
string num, fnum;
a = abs(x);
try{
while(a != 0){
r = a % 10;
a = a / 10;
num = to_string(r);
fnum = fnum + num;
y = stoi(fnum);
}
} catch(out_of_range& oor){
return 0;
}
if(x==0){
return 0;
} else if (x<0){
return -y;
} else {
return y;
}
}
};
int main(){
Solution mine;
cout << mine.reverse(-2147483648);
}
[...] when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
That number is "tricky" because it's equal to std::numeric_limits<int>::min() in your environment and given a two's complement representation of type int, it happens that std::abs(-2147483648) == -2147483648.
Next in your (contrived, I must say, there's no need to use a string here) code, the line num = to_string(r); would result in num = "-8", so that the loop would compose a string like "-8-4-6-3-8-4-7-4-1-2".
When applyed to strings like that, stoi doesn't throw an exception, it just stops parsing (you would have noticed it by passing and inspecting its other parameters).
If you want to check if the result is outside the range of an int, you could use locally a wider type (e.g. long long) and check the boundaries after the calculations or keep using int, but compare all the intermediate values with the limits before any calculation.

Time limit exceeded issue in c++ UVa problem for university homework

I have a Time limit exceeded issue in problem 100 from UVa.
the question is here:
https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=36
Here is my code. Please help me find a solution. How can I avoid such problems?
I don't know if it is the problem with cin and cout or the while loops? this program works well in my terminal when I run it.
#include <iostream>
using namespace std;
int main()
{
int i , j, temp, n;
while (cin >> i >> j) //asking for user input
{
int x, y;
x = i;
y = j;
if (i > j) //sorting i and j to fix the order of numbers
{
temp = j;
j = i;
i = temp;
}
int answer = 0;
int counter;
while (i <= j)
{
n = i;
counter = 1; // make the value of counter to 1 because it increases if i is 1
while (1)
{
if(n == 1) { //if n = 1 then stop
break;
} else if (n % 2 == 0) //cheak if i is odd
{
n = (3 % n) + 1;
} else {
n = n / 2; //cheak if i is even
}
counter++; //increase by one for every number that is not 1
}
if (counter > answer)
{
answer = counter;
}
i++;
}
cout << x << " " << y << " " << answer << "\n";
}
return 0;
}
Thanks in advance
In my humble opinion this problem is not about calculating the resulting values using the given algorithm. Because of the simplicity this is just some noise. So,maybe we are talking about a XY Problem here.
Maybe I am wrong, but the main problem here seems to be memoization.
It maybe that values need to be calculated over and over again, because they are in some overlapped range. And this is not necessary.
So, we could memorize already calculated values, for example in a std::unordered_map (or std::map). So, something like in the below:
unsigned int getSteps(size_t index) noexcept {
unsigned counter{};
while (index != 1) {
if (index % 2) index = index * 3 + 1;
else index /= 2;
++counter;
}
return counter+1;
}
unsigned int getStepsMemo(size_t index) {
// Here we will memorize whatever we calculated before
static std::unordered_map<unsigned int, unsigned int> memo{};
// Resulting value
unsigned int result{};
// Look, if we did calculate the value in the past
auto iter = memo.find(index);
if (iter != memo.end())
// If yes, then reuse old value
result = iter->second;
else {
// If no, then calculate new and memorize it
result = getSteps(index);
memo[index] = result;
}
return result;
}
This will help with many given input pairs. It will avoid recalculating steps for already calculated values.
But having thought in this direction, we can also calculate all values at compile time and store them in a constexpr std::array. Then no calculation will be done during runtime. All steps for any number up to 10000 will be precalculated. So, the algorithm will never be called during runtime.
It should be clear that this is the fastest possible algorithm, because we do nothing. Just get the value from a lookup table.
And if we want to make things nice, then we pack everything in a class and let the class encapsulate the problem. Even input and output operatores will be overwritten and used for our own purposes.
And in the end, we will have an ultra fast one liner in our function main. Please see:
#include <iostream>
#include <utility>
#include <sstream>
#include <array>
#include <algorithm>
#include <iterator>
#include <unordered_map>
// All done during compile time -------------------------------------------------------------------
constexpr unsigned int getSteps(size_t index) noexcept {
unsigned counter{};
while (index != 1) {
if (index % 2) index = index * 3 + 1;
else index /= 2;
++counter;
}
return counter+1;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices+1)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
constexpr size_t MaxIndex = 10000;
// This is the definition of a std::array<unsigned long long, 10000> with all step counts
constexpr auto steps = generateArray<MaxIndex>(getSteps);
// End of: All done during compile time -----------------------------------------------------------
// Some very simple helper class for easier handling of the functionality
struct StepsForPair {
// A pair with special functionality
unsigned int first{};
unsigned int second{};
// Simple extraction operator. Read 2 values
friend std::istream& operator >> (std::istream& is, StepsForPair& sfp) {
return is >> sfp.first >> sfp.second;
}
// Simple inserter. Sort first and second value and show result
friend std::ostream& operator << (std::ostream& os, const StepsForPair& sfp) {
unsigned int f{ sfp.first }, s{ sfp.second };
if (f > s) std::swap(f, s);
return os << sfp.first << ' ' << sfp.second << ' ' << *std::max_element(&steps[f], &steps[s]);
}
};
// Some test data. I will not use std::cin, but read from this std::istringstream here
std::istringstream testData{ R"(1 10
100 200
201 210
900 1000
22 22)" };
int main() {
// Read all input data and generate output
std::copy(std::istream_iterator<StepsForPair>(testData), {}, std::ostream_iterator<StepsForPair>(std::cout,"\n"));
}
Please note, since I do not have std::cin here on SO, I read the test values from a std::istringstream. Because of the overwritten extractor operator, this is easily possible.
If you want to read from std::cin then please replace in the std::copy statement in main "testData" eith "std::cin".
If you want to read from a file, then put a fileStream variable in there.
In this line n = (3 % n) + 1;, (3 % n) means that you take the remainder of 3 divided by n, which is probably not what you want. Change that to 3 * n

Converting an array of 2 digit numbers into an integer (C++)

Is it possible to take an array filled with 2 digit numbers e.g.
[10,11,12,13,...]
and multiply each element in the list by 100^(position in the array) and sum the result so that:
mysteryFunction[10,11,12] //The function performs 10*100^0 + 11*100^1 + 12*100^3
= 121110
and also
mysteryFunction[10,11,12,13]
= 13121110
when I do not know the number of elements in the array?
(yes, the reverse of order is intended but not 100% necessary, and just in case you missed it the first time the numbers will always be 2 digits)
Just for a bit of background to the problem: this is to try to improve my attempt at an RSA encryption program, at the moment I am multiplying each member of the array by 100^(the position of the number) written out each time which means that each word which I use to encrypt must be a certain length.
For example to encrypt "ab" I have converted it to an array [10,11] but need to convert it to 1110 before I can put it through the RSA algorithm. I would need to adjust my code for if I then wanted to use a three letter word, again for a four letter word etc. which I'm sure you will agree is not ideal. My code is nothing like industry standard but I am happy to upload it should anyone want to see it (I have also already managed this in Haskell if anyone would like to see that). I thought that the background information was necessary just so that I don't get hundreds of downvotes from people thinking that I'm trying to trick them into doing homework for me. Thank you very much for any help, I really do appreciate it!
EDIT: Thank you for all of the answers! They perfectly answer the question that I asked but I am having problems incorporating them into my current program, if I post my code so far would you be able to help? When I tried to include the answer provided I got an error message (I can't vote up because I don't have enough reputation, sorry that I haven't accepted any answers yet).
#include <iostream>
#include <string>
#include <math.h>
int returnVal (char x)
{
return (int) x;
}
unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
unsigned long long remainder;
int x = 1;
while (e != 0)
{
remainder = e % 2;
e= e/2;
if (remainder == 1)
x = (x * b) % m;
b= (b * b) % m;
}
return x;
}
int main()
{
unsigned long long p = 80001;
unsigned long long q = 70021;
int e = 7;
unsigned long long n = p * q;
std::string foo = "ab";
for (int i = 0; i < foo.length(); i++);
{
std::cout << modExp (returnVal((foo[0]) - 87) + returnVal (foo[1] -87) * 100, e, n);
}
}
If you want to use plain C-style arrays, you will have to separately know the number of entries. With this approach, your mysterious function might be defined like this:
unsigned mysteryFunction(unsigned numbers[], size_t n)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < n; ++i)
{
result += factor * numbers[i];
factor *= 100;
}
return result;
}
You can test this code with the following:
#include <iostream>
int main()
{
unsigned ar[] = {10, 11, 12, 13};
std::cout << mysteryFunction(ar, 4) << "\n";
return 0;
}
On the other hand, if you want to utilize the STL's vector class, you won't separately need the size. The code itself won't need too many changes.
Also note that the built-in integer types cannot handle very large numbers, so you might want to look into an arbitrary precision number library, like GMP.
EDIT: Here's a version of the function which accepts a std::string and uses the characters' ASCII values minus 87 as the numbers:
unsigned mysteryFunction(const std::string& input)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < input.size(); ++i)
{
result += factor * (input[i] - 87);
factor *= 100;
}
return result;
}
The test code becomes:
#include <iostream>
#include <string>
int main()
{
std::string myString = "abcde";
std::cout << mysteryFunction(myString) << "\n";
return 0;
}
The program prints: 1413121110
As benedek mentioned, here's an implementation using dynamic arrays via std::vector.
unsigned mystery(std::vector<unsigned> vect)
{
unsigned result = 0;
unsigned factor = 1;
for (auto& item : vect)
{
result += factor * item;
factor *= 100;
}
return result;
}
void main(void)
{
std::vector<unsigned> ar;
ar.push_back(10);
ar.push_back(11);
ar.push_back(12);
ar.push_back(13);
std::cout << mystery(ar);
}
I would like to suggest the following solutions.
You could use standard algorithm std::accumulate declared in header <numeric>
For example
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s =
std::accumulate( std::begin( a ), std::end( a ), 0ull,
[&]( unsigned long long acc, unsigned int x )
{
return ( acc += x * i, i *= 100, acc );
} );
std::cout << "s = " << s << std::endl;
return 0;
}
The output is
s = 13121110
The same can be done with using the range based for statement
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s = 0;
for ( unsigned int x : a )
{
s += x * i; i *= 100;
}
std::cout << "s = " << s << std::endl;
return 0;
}
You could also write a separate function
unsigned long long mysteryFunction( const unsigned int a[], size_t n )
{
unsigned long long s = 0;
unsigned long long i = 1;
for ( size_t k = 0; k < n; k++ )
{
s += a[k] * i; i *= 100;
}
return s;
}
Also think about using std::string instead of integral numbers to keep an encrypted result.

factorial of big numbers with strings in c++

I am doing a factorial program with strings because i need the factorial of Numbers greater than 250
I intent with:
string factorial(int n){
string fact="1";
for(int i=2; i<=n; i++){
b=atoi(fact)*n;
}
}
But the problem is that atoi not works. How can i convert my string in a integer.
And The most important Do I want to know if the program of this way will work with the factorial of 400 for example?
Not sure why you are trying to use string. Probably to save some space by not using integer vector? This is my solution by using integer vector to store factorial and print.Works well with 400 or any large number for that matter!
//Factorial of a big number
#include<iostream>
#include<vector>
using namespace std;
int main(){
int num;
cout<<"Enter the number :";
cin>>num;
vector<int> res;
res.push_back(1);
int carry=0;
for(int i=2;i<=num;i++){
for(int j=0;j<res.size();j++){
int tmp=res[j]*i;
res[j]=(tmp+carry)%10 ;
carry=(tmp+carry)/10;
}
while(carry!=0){
res.push_back(carry%10);
carry=carry/10;
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
return 0;
}
Enter the number :400
Factorial of 400 :64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
There's a web site that will calculate factorials for you: http://www.nitrxgen.net/factorialcalc.php. It reports:
The resulting factorial of 250! is 493 digits long.
The result also contains 62 trailing zeroes (which constitutes to 12.58% of the whole number)
3232856260909107732320814552024368470994843717673780666747942427112823747555111209488817915371028199450928507353189432926730931712808990822791030279071281921676527240189264733218041186261006832925365133678939089569935713530175040513178760077247933065402339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000
Many systems using C++ double only work up to 1E+308 or thereabouts; the value of 250! is too large to store in such numbers.
Consequently, you'll need to use some sort of multi-precision arithmetic library, either of your own devising using C++ string values, or using some other widely-used multi-precision library (GNU GMP for example).
The code below uses unsigned double long to calculate very large digits.
#include<iostream.h>
int main()
{
long k=1;
while(k!=0)
{
cout<<"\nLarge Factorial Calculator\n\n";
cout<<"Enter a number be calculated:";
cin>>k;
if (k<=33)
{
unsigned double long fact=1;
fact=1;
for(int b=k;b>=1;b--)
{
fact=fact*b;
}
cout<<"\nThe factorial of "<<k<<" is "<<fact<<"\n";
}
else
{
int numArr[10000];
int total,rem=0,count;
register int i;
//int i;
for(i=0;i<10000;i++)
numArr[i]=0;
numArr[10000]=1;
for(count=2;count<=k;count++)
{
while(i>0)
{
total=numArr[i]*count+rem;
rem=0;
if(total>9)
{
numArr[i]=total%10;
rem=total/10;
}
else
{
numArr[i]=total;
}
i--;
}
rem=0;
total=0;
i=10000;
}
cout<<"The factorial of "<<k<<" is \n\n";
for(i=0;i<10000;i++)
{
if(numArr[i]!=0 || count==1)
{
cout<<numArr[i];
count=1;
}
}
cout<<endl;
}
cout<<"\n\n";
}//while
return 0;
}
Output:
![Large Factorial Calculator
Enter a number be calculated:250
The factorial of 250 is
32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]
You can make atoi compile by adding c_str(), but it will be a long way to go till getting factorial. Currently you have no b around. And if you had, you still multiply int by int. So even if you eventually convert that to string before return, your range is still limited. Until you start to actually do multiplication with ASCII or use a bignum library there's no point to have string around.
Your factorial depends on conversion to int, which will overflow pretty fast, so you want be able to compute large factorials that way. To properly implement computation on big numbers you need to implement logic as for computation on paper, rules that you were tought in primary school, but treat long long ints as "atoms", not individual digits. And don't do it on strings, it would be painfully slow and full of nasty conversions
If you are going to solve factorial for numbers larger than around 12, you need a different approach than using atoi, since that just gives you a 32-bit integer, and no matter what you do, you are not going to get more than 2 billion (give or take) out of that. Even if you double the size of the number, you'll only get to about 20 or 21.
It's not that hard (relatively speaking) to write a string multiplication routine that takes a small(ish) number and multiplies each digit and ripples the results through to the the number (start from the back of the number, and fill it up).
Here's my obfuscated code - it is intentionally written such that you can't just take it and hand in as school homework, but it appears to work (matches the number in Jonathan Leffler's answer), and works up to (at least) 20000! [subject to enough memory].
std::string operator*(const std::string &s, int x)
{
int l = (int)s.length();
std::string r;
r.resize(l);
std::fill(r.begin(), r.end(), '0');
int b = 0;
int e = ~b;
const int c = 10;
for(int i = l+e; i != e;)
{
int d = (s[i]-0x30) * x, p = i + b;
while (d && p > e)
{
int t = r[p] - 0x30 + (d % c);
r[p] = (t % c) + 0x30;
d = t / c + d / c;
p--;
}
while (d)
{
r = static_cast<char>((d % c) +0x30)+r;
d /= c;
b++;
}
i--;
}
return r;
}
In C++, the largest integer type is 'long long', and it hold 64 bits of memory, so obviously you can't store 250! in an integer type. It is a clever idea to use strings, but what you are basically doing with your code is (I have never used the atoi() function, so I don't know if it even works with strings larger than 1 character, but it doesn't matter):
covert the string to integer (a string that if this code worked well, in one moment contains the value of 249!)
multiply the value of the string
So, after you are done multiplying, you don't even convert the integer back to string. And even if you did that, at one moment when you convert the string back to an integer, your program will crash, because the integer won't be able to hold the value of the string.
My suggestion is, to use some class for big integers. Unfortunately, there isn't one available in C++, so you'll have to code it by yourself or find one on the internet. But, don't worry, even if you code it by yourself, if you think a little, you'll see it's not that hard. You can even use your idea with the strings, which, even tough is not the best approach, for this problem, will still yield the results in the desired time not using too much memory.
This is a typical high precision problem.
You can use an array of unsigned long long instead of string.
like this:
struct node
{
unsigned long long digit[100000];
}
It should be faster than string.
But You still can use string unless you are urgent.
It may take you a few days to calculate 10000!.
I like use string because it is easy to write.
#include <bits/stdc++.h>
#pragma GCC optimize (2)
using namespace std;
const int MAXN = 90;
int n, m;
int a[MAXN];
string base[MAXN], f[MAXN][MAXN];
string sum, ans;
template <typename _T>
void Swap(_T &a, _T &b)
{
_T temp;
temp = a;
a = b;
b = temp;
}
string operator + (string s1, string s2)
{
string ret;
int digit, up = 0;
int len1 = s1.length(), len2 = s2.length();
if (len1 < len2) Swap(s1, s2), Swap(len1, len2);
while(len2 < len1) s2 = '0' + s2, len2++;
for (int i = len1 - 1; i >= 0; i--)
{
digit = s1[i] + s2[i] - '0' - '0' + up; up = 0;
if (digit >= 10) up = digit / 10, digit %= 10;
ret = char(digit + '0') + ret;
}
if (up) ret = char(up + '0') + ret;
return ret;
}
string operator * (string str, int p)
{
string ret = "0", f; int digit, mul;
int len = str.length();
for (int i = len - 1; i >= 0; i--)
{
f = "";
digit = str[i] - '0';
mul = p * digit;
while(mul)
{
digit = mul % 10 , mul /= 10;
f = char(digit + '0') + f;
}
for (int j = 1; j < len - i; j++) f = f + '0';
ret = ret + f;
}
return ret;
}
int main()
{
freopen("factorial.out", "w", stdout);
string ans = "1";
for (int i = 1; i <= 5000; i++)
{
ans = ans * i;
cout << i << "! = " << ans << endl;
}
return 0;
}
Actually, I know where the problem raised At the point where we multiply , there is the actual problem ,when numbers get multiplied and get bigger and bigger.
this code is tested and is giving the correct result.
#include <bits/stdc++.h>
using namespace std;
#define mod 72057594037927936 // 2^56 (17 digits)
// #define mod 18446744073709551616 // 2^64 (20 digits) Not supported
long long int prod_uint64(long long int x, long long int y)
{
return x * y % mod;
}
int main()
{
long long int n=14, s = 1;
while (n != 1)
{
s = prod_uint64(s , n) ;
n--;
}
}
Expexted output for 14! = 87178291200
The logic should be:
unsigned int factorial(int n)
{
unsigned int b=1;
for(int i=2; i<=n; i++){
b=b*n;
}
return b;
}
However b may get overflowed. So you may use a bigger integral type.
Or you can use float type which is inaccurate but can hold much bigger numbers.
But it seems none of the built-in types are big enough.