2016-02-09 2 views
-1

В моем домашней работе я далСоздания большого целого 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; 
} 
+1

Так ли цель работать с классом BigInteger или динамическим массивом? Если это первый, используйте 'std :: vector' и удалите ручное управление памятью. После этого проблему можно решить на более высоком уровне вместо того, чтобы попасть в сорняки 'new []/delete []'. И если ответ «Я не могу использовать вектор», использование вектора не делает класс BigInteger. То, что он делает ** делает, это заставить вас начать писать код, чтобы сделать такой класс без хлопот. – PaulMcKenzie

+0

Вот пример без ручного управления памятью. http://ideone.com/Kizzp1 Нет необходимости в конструкторе копирования, операторе присваивания, деструкторе. Все, что мы делаем, это вызвать 'resize', чтобы установить динамический массив в новый размер. Теперь ни один из кода для создания BigInteger из строки не был закодирован. Но, по крайней мере, у вас есть сплошной класс barebones, а не один, основанный на багги базовом коде с ручным управлением памятью. – PaulMcKenzie

+1

Кроме того, если по какой-то причине вы должны использовать ручное управление памятью, вы все равно должны использовать образец кода, по крайней мере, для кода конструктора для версии 'std :: string'. Затем, если это работает, ** затем ** вы пытаетесь переписать его с помощью ручного управления памятью, с полным пониманием того, что, по крайней мере, вы/находились на правильном пути. – PaulMcKenzie

ответ

0

У вас уже есть код, чтобы сохранить целое значение в BigInteger, в функции multiply. Код, который сохраняет остальную часть carry (в конце), сохраняет его в BigInteger. Используйте это как пример.

Для строки, вам нужно просто поместить цифры из строки в объект BigInteger в обратном порядке.