保存在String Object中的HugeInteger对象的位数
Digits of a HugeInteger Object Stored in a String Object
我正在研究一个巨大的整数问题,我必须创建一个HugeInteger类,其中数字将存储在字符串对象中,而不是固定(静态)大小的无符号短裤数组。我被困在如何实现这一点。当我运行程序时,我为我的HugeInteger对象输入值,但是之后什么也没有显示。我很感激你的帮助。提前感谢。
下面是我到目前为止所拥有的源代码。
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( char *str);
//Convert a string into a HugeInteger
void input( char *str);
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 <iostream>
using namespace std;
// ctor converts a long long into a HugeInteger
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(char *str)
{
this->input(str); //See HugeInteger::input() method below
}
void HugeInteger::input( char *str)
{
// assume positive for now
this->negative = false;
// init. to all zeros first
unsigned int i = 0;
cin.getline(str, sizeof str);
cin.sync();
cin.clear();
while (i < strlen(str) - 1)
{
if (isdigit(str[i]))
{
this->hugeInt[i] = str[i];
i++;
}
}
istream & operator>>(istream & input, HugeInteger & value)
{
char inputString[1002];
input >> inputString;
value.input(inputString);
return input;
}
ostream & operator << (ostream & output, const HugeInteger & value)
{
// find first non-zero digit
unsigned int i = 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;
}
MainProg.cpp
#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;
system("pause");
return 0;
} // end main
你的代码有几个问题,但最明显的是你的输入函数。
首先,为什么HugeInteger::input
需要知道如何检索输入?不需要cin
或任何I/O -它的工作是单独采用char *
指针,并通过它循环创建hugeInt
字符串。
因此,下面的行应该被删除:
cin.getline(str, sizeof str);
cin.sync();
cin.clear();
下一个问题是实际的循环。它有几个问题。
首先,无论字符是否是数字,您都应该增加i
。否则,如果字符不是数字,则将进入无限循环。
第二,当您构建hugeInt
字符串时,您应该将字符连接到字符串上。您当前的代码导致未定义的行为,因为您正在访问hugeInt[i]
,而hugeInt
是一个空字符串,因此没有i
条目。
所以这里的变化是:
while (i < strlen(str) - 1)
{
if (isdigit(str[i]))
this->hugeInt += str[i];
i++;
}
现在,一个更好的实现是让input
接受std::string
,而不是char*。现在,整个函数将被重写如下:
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++;
}
}
最后一个问题是你的operator >>
。没有必要将自己限制在1002个字符。只需输入std::string
.
istream & operator>>(istream & input, HugeInteger & value)
{
string inputString;
input >> inputString;
value.input(inputString);
return input;
}
经过这些修改后,示例可以正常运行:http://ideone.com/F47TEV
编辑:使用STL算法函数提取数字并添加到字符串上的另一种方法如下:
void HugeInteger::input(std::string str)
{
// assume positive for now
this->negative = false;
str.erase(std::remove_if(str.begin(), str.end(), [](char ch)
{ return !isdigit(ch);}), str.end());
hugeInt = str;
}
std::remove_if
是稳定的,所以数字的相对顺序不会改变。还请注意,我们是按值传递的,因为这给了编译器(如果是c++ 11)一个很好的机会来优化传递的副本(而不是在函数中创建自己的副本)。
你当前的代码导致未定义的行为,因为你正在访问hugeInt[i],而hugeInt是一个空字符串,所以没有i条目。
再加上
行for (; i < hugeInt.size(); i++)
和
for (unsigned int j = hugeInt.size() - 1; j >= 0 && value != 0LL; j--)
将永远不会开始执行,因为hugeInt.size()
将为0,并且for
循环条件永远不会满足
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 正在添加HugeInteger字符串对象
- 保存在String Object中的HugeInteger对象的位数