факториал больших чисел со строками в переполнении стека

Я делаю факториальную программу со строками, потому что мне нужен факториал чисел больше 250

Я намерен с:

string factorial(int n){
string fact="1";
for(int i=2; i<=n; i++){
b=atoi(fact)*n;

}

}

Но проблема в том, что atoi не работает. Как я могу преобразовать мою строку в целое число.

И самое главное, хочу ли я знать, будет ли программа этого способа работать с факториалом 400, например?

2

Решение

Есть веб-сайт, который будет рассчитывать факториалы для вас: http://www.nitrxgen.net/factorialcalc.php. Это сообщает:

Получившийся факториал 250! длиной 493 цифры.
Результат также содержит 62 конечных нуля (что составляет 12,58% от общего числа)

3232856260909107732320814552024368470994843717673780666747942427112823747555111209488817915371028199450928507353189432926730931712808990822791030279071281921676527240189264733218041186261006832925365133678939089569935713530175040513178760077247933065402339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000

Многие системы используют C ++ double работать только до 1E + 308 или около того; стоимость 250! слишком велик, чтобы хранить в таких количествах.

Следовательно, вам нужно будет использовать некую арифметическую библиотеку с высокой точностью, либо вашу собственную разработку с использованием C ++. string значения, или с использованием какой-либо другой широко используемой библиотеки мульти-точности (GNU GMP например).

3

Другие решения

Код ниже использует unsigned double long рассчитать очень большие цифры.

#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;

}

Выход:

![Large Factorial Calculator

Enter a number be calculated:250
The factorial of 250 is

32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]
1

Не уверен, почему вы пытаетесь использовать строку. Возможно, чтобы сэкономить место, не используя целочисленный вектор? Это мое решение с использованием целочисленного вектора для хранения факториала и печати. ​​Работает хорошо с 400 или любым большим числом в этом отношении!

//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;
}

Введите число: 400
Факториал 400: 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

1

Вы можете сделать компиляцию atoi, добавив c_str (), но до получения факториала будет долгий путь. В настоящее время у вас нет б вокруг. И если бы вы имели, вы все равно умножаете int на int. Так что даже если вы в конечном итоге преобразуете это в строку перед возвратом, ваш диапазон все еще ограничен. Пока вы не начнете фактически умножать с ASCII или не будете использовать библиотеку bignum, нет смысла хранить строку вокруг.

0

Ваш факториал зависит от преобразования в int, которое довольно быстро переполняется, поэтому вы хотите иметь возможность вычислять большие факториалы таким образом. Чтобы правильно реализовать вычисления для больших чисел, вам нужно реализовать логику, как для вычислений на бумаге, правила, которые вы изучали в начальной школе, но рассматривали длинные длинные целые числа как «атомы», а не отдельные цифры. И не делайте этого на строках, это будет мучительно медленно и полно отвратительных обращений

0

Логика должна быть:

unsigned int factorial(int n)
{
unsigned int b=1;
for(int i=2; i<=n; i++){
b=b*n;
}
return b;
}

Однако b может быть переполнен. Таким образом, вы можете использовать больший целочисленный тип.
Или вы можете использовать тип с плавающей точкой, который является неточным, но может содержать гораздо большие числа.
Но кажется, что ни один из встроенных типов не является достаточно большим.

0

Если вы собираетесь вычислять факториал для чисел больше 12, вам нужен другой подход, чем использование atoiТак как это просто дает вам 32-разрядное целое число, и независимо от того, что вы делаете, вы не получите от этого более 2 миллиардов (отдавать или брать). Даже если вы удвоите размер числа, вы получите только около 20 или 21.

Нетрудно (условно говоря) написать процедуру умножения строк, которая принимает небольшое число (ish) и умножает каждую цифру и перебрасывает результаты в число (начинайте с конца числа и заполняйте его).

Вот мой запутанный код — он специально написан так, что вы не можете просто взять его и сдать в качестве школьной домашней работы, но он, кажется, работает (соответствует числу в ответе Джонатана Леффлера) и работает до (как минимум) 20000! [при условии достаточной памяти].

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;
}
0

В C ++ самый большой целочисленный тип — это long long, и он содержит 64 бита памяти, поэтому, очевидно, вы не можете хранить 250! в целочисленном виде. Это умная идея использовать строки, но то, что вы в основном делаете со своим кодом: (я никогда не использовал функцию atoi (), поэтому я не знаю, работает ли она даже со строками, длина которых превышает 1 символ, но это не не имеет значения):

  1. преобразовать строку в целое число (строка, которая, если этот код работал хорошо, в один момент содержит значение 249!)
  2. умножить значение строки

Итак, после того, как вы закончите умножение, вы даже не преобразуете целое число обратно в строку. И даже если вы это сделаете, в один момент, когда вы преобразуете строку обратно в целое число, ваша программа потерпит крах, потому что целое число не сможет содержать значение строки.

Я предлагаю использовать некоторый класс для больших целых чисел. К сожалению, в C ++ такого нет, поэтому вам придется самостоятельно его кодировать или найти в Интернете. Но не волнуйтесь, даже если вы закодируете это самостоятельно, если немного подумаете, то увидите, что это не так сложно. Вы даже можете использовать свою идею со строками, что, даже если это не самый лучший подход, для этой проблемы все равно даст результаты в нужное время, не используя слишком много памяти.

0
По вопросам рекламы [email protected]