В моем домашней работе я далСоздания большого целого C++
BigInteger::BigInteger(int val) {
и
BigInteger::BigInteger(string str) {
Я должен реализовать два конструктора для инициализации объекта BigInteger из целочисленного значения и строк сохраняя целое значение. Мне действительно нужно всего лишь шаг в правильном направлении, потому что я просто не знаю, как начать это.
Он также упоминает, что это может быть полезно для него
void BigInteger::setDigit(int pos, char digit)
{
if (pos >= size)
{ // not enough space
int newSize = 1;
while (newSize <= pos)
newSize *= 2; // compute newSize as a power of 2 that is bigger than pos
char* temp = digits; // store link to current digits
digits = new char[newSize]; // allocate a new array
memset(digits, 0, newSize); // and fill zeros
if (temp != NULL) // if there are some current digits
memcpy(digits, temp, nDigits); // copy them
size = newSize;
}
digits[pos] = digit; // put the given digit at position pos
if (pos >= nDigits) // update the number of digits!
nDigits = pos + 1;
}
Вот определение класса
class BigInteger
{
private:
char* digits; // the array storing digits
int size; // the current size of digits array
int nDigits; // the current number of digits
void init(int size);
void copy(const BigInteger &num);
public:
BigInteger(); // Default constructor
~BigInteger(); // Default destructor
BigInteger(int val); // Initialize a BigInteger with an integer value
BigInteger(string str); // Initialize a BigInteger with a string storing a number
BigInteger(const BigInteger &num); // Copy constructor
BigInteger& operator=(const BigInteger &num); // Copy assignment operator
int numberOfDigits() const
{
return nDigits;
}
char getDigit(int pos) const; // get the digit at position pos
void setDigit(int pos, char digit); // set the digit at position pos
void print(bool debug = true);
};
Цель Окончательный домашней работы должен быть в состоянии вычислить 999! (1 * 2 * 3 * .... 999)
Как я уже сказал, шаг в правильном направлении будет оценен.
Вот весь код:
#include"BigInteger.h"
BigInteger::BigInteger()
{
digits = NULL; // Default constructor: storing nothing!
size = 0;
nDigits = 0;
}
BigInteger::~BigInteger()
{
if (digits != NULL)
delete[] digits;
digits = NULL;
size = 0;
nDigits = 0;
}
void BigInteger::init(int size)
{
// Task 1. Allocate memory for digits and fill them as zeros
digits = new char[size];
for (int i = 0; i < size; i++)
{
digits[i] = 0;
}
}
void BigInteger::copy(const BigInteger &num)
{
size = num.size; // copy digits array size
nDigits = num.nDigits; // copy number of digits
digits = new char[size]; // allocate a new digits array with the same size in num
memcpy(digits, num.digits, size); // copy digits array
}
BigInteger::BigInteger(const BigInteger &num)
{ // Copy constructor
copy(num);
}
BigInteger& BigInteger::operator=(const BigInteger &num)
{
if (this != &num)
{ // not assign to the same object
if (digits != NULL)
delete[] digits; // release current digits array
copy(num);
}
return *this;
}
BigInteger::BigInteger(int val)
{
// Task 2a. Construct a BigInteger from an int value
}
BigInteger::BigInteger(string str)
{
// Task 2b. Construct a BigInteger from a string.
}
char BigInteger::getDigit(int pos) const
{
if (pos >= nDigits)
return 0;
else
return digits[pos];
}
void BigInteger::setDigit(int pos, char digit)
{
if (pos >= size)
{ // not enough space
int newSize = 1;
while (newSize <= pos)
newSize *= 2; // compute newSize as a power of 2 that is bigger than pos
char* temp = digits; // store link to current digits
digits = new char[newSize]; // allocate a new array
memset(digits, 0, newSize); // and fill zeros
if (temp != NULL) // if there are some current digits
memcpy(digits, temp, nDigits); // copy them
size = newSize;
}
digits[pos] = digit; // put the given digit at position pos
if (pos >= nDigits) // update the number of digits!
nDigits = pos + 1;
}
BigInteger multiply(BigInteger &x, int y, int pos = 0)
{
int nx = x.numberOfDigits();
BigInteger z;
int carry = 0;
for (int i = 0; i < nx; i++)
{
carry += x.getDigit(i) * y;
z.setDigit(pos++, carry % 10);
carry /= 10;
}
while (carry > 0)
{
z.setDigit(pos++, carry % 10);
carry /= 10;
}
return z;
}
void BigInteger::print(bool debug)
{
if (digits == NULL)
cout << '0';
else
for (int i = nDigits; --i >= 0;)
cout << (int) digits[i];
if (debug)
printf(" [digits = %x, size = %d, nDigits = %d] ",
digits,
size,
nDigits);
}
ostream& operator<<(ostream& out, BigInteger num)
{
//Task 3. Overload operattor << to write a BigInteger object to screen
num.print();
return out;
}
Так ли цель работать с классом BigInteger или динамическим массивом? Если это первый, используйте 'std :: vector' и удалите ручное управление памятью. После этого проблему можно решить на более высоком уровне вместо того, чтобы попасть в сорняки 'new []/delete []'. И если ответ «Я не могу использовать вектор», использование вектора не делает класс BigInteger. То, что он делает ** делает, это заставить вас начать писать код, чтобы сделать такой класс без хлопот. – PaulMcKenzie
Вот пример без ручного управления памятью. http://ideone.com/Kizzp1 Нет необходимости в конструкторе копирования, операторе присваивания, деструкторе. Все, что мы делаем, это вызвать 'resize', чтобы установить динамический массив в новый размер. Теперь ни один из кода для создания BigInteger из строки не был закодирован. Но, по крайней мере, у вас есть сплошной класс barebones, а не один, основанный на багги базовом коде с ручным управлением памятью. – PaulMcKenzie
Кроме того, если по какой-то причине вы должны использовать ручное управление памятью, вы все равно должны использовать образец кода, по крайней мере, для кода конструктора для версии 'std :: string'. Затем, если это работает, ** затем ** вы пытаетесь переписать его с помощью ручного управления памятью, с полным пониманием того, что, по крайней мере, вы/находились на правильном пути. – PaulMcKenzie