正在添加HugeInteger字符串对象

Adding HugeInteger String Objects

本文关键字:字符串 对象 HugeInteger 添加      更新时间:2023-10-16

基本上,这个问题应该创建一个使用字符串存储数字的类HugeInteger。我必须添加HugeInteger对象。当我添加小整数(即3.4)时,该程序可以工作,然而,当我运行该程序并输入2个值(即1000000000000000000000000000000000000000000001)时,程序似乎冻结了,没有显示任何内容。非常感谢您的帮助。提前谢谢。

这是我的密码。

HugeInteger.h

#include <iostream>
#include <array>
#include <string>
class HugeInteger
{
    // need to offer friendship to these 2 functions
    friend std::istream & operator >> (std::istream & src, HugeInteger & value);
    friend std::ostream & operator << (std::ostream & dest, const HugeInteger & value);
public:
    //ctor that converts a "long long" into a HugeInteger
    HugeInteger(long long value = 0LL); //0LL is constant literal value 0
    //   of type long long
    //ctor that converts a string into a HugeInteger
    HugeInteger(const char *str);
    //Convert a string into a HugeInteger
    void input(const std::string& str);
    //adds RHS into LHS (the object pointed to by the "this" pointer) and returns result
    HugeInteger & operator +=(const HugeInteger & RHS);
    //adds a "long long" (RHS) and LHS and puts result into a temp HugeInteger
    //   and returns result
    HugeInteger operator +(long long RHS) const;
    //adds a string (which will be converted into a HugeInteger) with LHS into a temp 
    //       HugeInteger and returns result
    HugeInteger operator +(const char * RHS) const;
    // overload preincrement operator for the HugeInteger class
    HugeInteger & operator ++ (void);
    // overload postincrement operator for the HugeInteger class
    HugeInteger operator ++ (int);
private:
    bool negative;  // will be true if number is negative
    std::string hugeInt; // each digit is stored in a string object
};
//overloads the << and >> operators for the HugeInteger class
std::istream & operator >> (std::istream & src, HugeInteger & value);
std::ostream & operator << (std::ostream & dest, const HugeInteger & value);

HugeInteger.cpp

#include "HugeInteger.h"
#include <sstream>
#include <ostream>
#include <iostream>
using namespace std;
HugeInteger::HugeInteger(long long value)
{
    // set all MaxDigit digits to zero to start
    this->negative = false;
    if (value < 0LL){ // 0LL is constant literal 0 of type long long
        this->negative = true;
        value = -value; // make the value positive                  
    }
    unsigned int i = 0;

    for (; i < hugeInt.size(); i++)
    {
        this->hugeInt[i] = '0';
    }
    this->hugeInt[i] = '';

    // convert individual digits of input value into a HugeInteger
    for (unsigned int j = hugeInt.size() - 1; j >= 0 && value != 0LL; j--)
    {
        short result = value % 10;
        char c = (char)result;
        this->hugeInt[j] = c;
        value /= 10;
    }
    // test to make sure that HugeInteger was able to contain value
    if (value != 0LL){
        *this = 0LL; // set to -0, to signal overflow
        this->negative = true; //   Possibly should increase value assigned
    }                          //   to MaxDigit to fix this problem.
}
// converts string into a HugeInteger object
HugeInteger::HugeInteger(const char *str)
{
    this->input(str);
}
// converts long long into HugeInteger and then invokes
//    HugeInteger::operator +=(const HugeInteger & )
HugeInteger HugeInteger::operator +(long long value) const
{
    HugeInteger temp = *this;
    return temp += (HugeInteger(value));
}

//converts string into HugeInteger and then invokes
//   HugeInteger::operator +=(const HugeInteger & )
HugeInteger HugeInteger::operator +(const char *str) const
{
    HugeInteger temp = *this;
    return temp += (HugeInteger(str));
}
// Adds into the HugeInteger pointed to by the "this" pointer 
//   the HugeInteger op.
//   Then the calculated result is returned
HugeInteger & HugeInteger::operator+=(const HugeInteger &op)
{
    int value = atoi(op.hugeInt.c_str());
    for (int i = value - 1; i >= 0; i--)
    {
        this->operator++();
    }
    return *this;
}

void HugeInteger::input(const std::string& str)
{
    // assume positive for now
    this->negative = false;
    // init. to all zeros first
    unsigned int i = 0;
    this->hugeInt.clear();
    while (i < str.size())
    {
        if (isdigit(str[i]))
            this->hugeInt += str[i];
        i++;
    }
}
// Pre-increment operator
HugeInteger & HugeInteger::operator ++ ()
{
    string key = this->hugeInt;
    istringstream in(key);
    int int_key;
    in >> int_key;
    int_key++;
    ostringstream out;
    out << int_key;
    key = out.str();
    this->hugeInt = key;
    return *this;
}
// Post-increment operator
HugeInteger HugeInteger::operator ++ (int)
{
    string key = this->hugeInt;
    istringstream in(key);
    int int_key;
    in >> int_key;
    int_key++;
    ostringstream out;
    out << int_key;
    key = out.str();
    HugeInteger temp = *this;
    this->hugeInt = key;
    return temp;
}
istream & operator>>(istream & input, HugeInteger & value)
{
    string inputString;
    input >> inputString;
    value.input(inputString);
    return input;
}
ostream & operator << (ostream & output, const HugeInteger & value)
{
    // find first non-zero digit
    unsigned int i = 0;
    if (value.hugeInt.size() == 0)
    {
        cout << '0';
    }
    while (i < value.hugeInt.size()){
        if (value.hugeInt[i] != '0'){
            break;
        }
        ++i;
    }
    // if all zeros, just output a single 0
    if (i == 40)
    {
        cout << '0';
        return output;
    }
    // check if we need to ouput a negative sign
    if (value.negative){
        cout << '-';
    }
    // output remaining digits
    for (; i < value.hugeInt.size(); i++)
    {
        cout << value.hugeInt[i];
    }
    return output;
}

主程序

#include "HugeInteger.h" // include definiton of class HugeInteger
using namespace std;
int main()
{
    HugeInteger A, B, C, D;
    // input value for A & B
    cout << "****** Test << & >> operators ******nn";
    cout << "Input values for A and B: ";
    cin >> A >> B;
    cout << "nA = " << A << "nB = " << B;
    D = B;
    // test += operator
    cout << "nn****** Test += operator ******nn";
    cout << "A = " << A << "nB = " << B << "nC = " << C << "nn";
    cout << "C = B += An";
    C = B += A;
    cout << "nA = " << A << "nB = " << B << "nC = " << C;
    B = D;  // restore B's value
    system("pause");
    return 0;
} // end main

不幸的是,存在一些严重的体系结构问题。最大的问题是加法算法通过循环使用++增量运算符来执行加法。

以下是添加C = A + B:期间发生的情况的演练

  • +运算符只是服从于+=运算符,这很好
  • 然后,+=运算符使用atoiB的字符串表示转换为整数这是第一个问题:如果HugeInt要容纳大于int所能容纳的整数,那么转换为int可能不是正确的方法
  • 然后通过执行CCD_ 10运算符CCD_如果你预计数字会很大,那么这将是一个非常低效的步骤。我建议你研究一个更好的加法算法
  • ++运算符中,创建一个输入字符串流和一个输出字符串流,以便将A的字符串表示转换为int,递增int,然后转换回要存储的字符串。就像我对+=运算符的评论一样,当HugeInt存储的数字大于最大的int时,转换为int是不合适的

不过,老实说,我不确定对于那个特定的组合,你是否会经历冻结,除非有一些未定义的行为将太长的字符串转换为整数。但我建议您提出一种不需要转换为int的存储机制和加法算法,因为这首先违背了HugeInt类的要点。