题目
用string模拟int大数运算,记得网易的一个笔试题最后就是的
调试错误解决
#include <string>依旧报错string未定义 因为木有using namespace std;
转换到 coff 期间失败 项目属性 — 配置属性 — 清单工具 — 点击输入输出 将右侧出现的嵌入清单的属性值修改为否,点击应用,点击确定
参考程序地址
github-BigInteger
Code
成员变量
private string num; // 数值 bool sign; //符号信息: true:负数 false:正数或者0 所以需要setNum,setSign和getNum,getSign
构造函数
1. BigInteger(); // empty constructor initializes zero
sign:false num = "0",初始化为0
2. BigInteger(string s); // "string" constructor
判断第一位 isdigit(s[0]) ,是,sign=false整数, 调用setNumber(s)
否,sign = (s[0] == '-'); 可能为+、-,调用 setNumber( s.substr(1) )从第二位(下标1)开始
3. BigInteger(string s, bool sin); // "string" constructor
直接调用 setNumber(s),setSign(sin)
4. BigInteger(int n); // "int" constructor
用到了stringstream作为中间,将int为变为string,同样判断是否正负,同2
附1: substr用法: substr 方法 返回一个从指定位置开始,并具有指定长度的子字符串。 参数 : start 必选。所需的子字符串的起始位置。字符串中第一个字符的索引为 0。 length : 可选项。返回的子字符串中包含的字符数。 备注 如果 length 为 0 或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到字符串的结尾。
附2:int–string
int n;
stringstream ss;
string s;
ss << n;
ss >> s;
成员函数set get
void BigInteger::setNumber(
string s) {
number = s;
}
const string& BigInteger::getNumber() {
return number;
}
void BigInteger::setSign(
bool s) {
sign = s;
}
const bool& BigInteger::getSign() {
return sign;
}
运算符重载
=,==,!=,>,<,>=,<=,++(前缀,后缀), --(前缀,后缀), +,-,/,%,+=,*=,/+,%= 这里重载了好多 不过可以明显从看到代码中 i++和++i的区别了 重载运算符,已经默认传了this指针
++i
BigInteger& BigInteger::
operator ++() {
(*
this) = (*
this) +
1;
return (*
this);
}
i++
BigInteger BigInteger::
operator ++(
int) {
BigInteger before = (*
this);
(*
this) = (*
this) +
1;
return before;
}
+
符号相同,那么设置符号,然后add符号不同,比较绝对值,取最大的,然后subtract判断是不是0,一面出现‘-0’的情况
BigInteger BigInteger
::operator + (BigInteger b) {
BigInteger addition;
if( getSign() == b.getSign() ) {
addition
.setNumber(
add(getNumber(), b.getNumber() ) );
addition
.setSign(
getSign() );
} else {
if( absolute() > b.absolute() ) {
addition
.setNumber(
subtract(getNumber(), b.getNumber() ) );
addition
.setSign(
getSign() );
} else {
addition
.setNumber(
subtract(b.getNumber(), getNumber() ) );
addition
.setSign(
b.getSign() );
}
}
if(addition.getNumber() == "0")
addition
.setSign(false);
return addition;
}
代码中看出来,this指针就是a咯,所以直接可用成员函数了
-
不需要判断符号了,直接变为+
BigInteger BigInteger::
operator - (BigInteger b) {
b.setSign( ! b.getSign() );
return (*
this) + b;
}
大于> 在判断绝对值的时候用到了重载的大于
bool BigInteger::
operator > (BigInteger b) {
return greater((*
this) , b);
}
计算函数
绝对值 直接返回getNum, 有够了一个BigInteger类,传string参数的那个构造函数
BigInteger
BigInteger::absolute() {
return BigInteger( getNumber() );
// +ve
by default
}
加法
和的长度:number1和number2中长度最大的赋值就好了,最后若为1,就insert1number1和number2相差几位,在前面补0number2.insert(0, differenceInLength, '0'); // put zeros from leftfor循环从后往前,设置char carry = ‘0’保留进位for循环中的要有判断i!=0,第一位的进位在外面处理处理最高位的进位加法运算实现:add[i] = ((carry-'0')+(number1[i]-'0')+(number2[i]-'0')) + '0';
string BigInteger::add(
string number1,
string number2) {
string add = (number1.length() > number2.length()) ? number1 : number2;
char carry =
'0';
int differenceInLength =
abs( (
int) (number1.
size() - number2.
size()) );
if(number1.
size() > number2.
size())
number2.insert(
0, differenceInLength,
'0');
else
number1.insert(
0, differenceInLength,
'0');
for(
int i=number1.
size()-
1; i>=
0; --i) {
add[i] = ((carry-
'0')+(number1[i]-
'0')+(number2[i]-
'0')) +
'0';
if(i !=
0) {
if(add[i] >
'9') {
add[i] -=
10;
carry =
'1';
}
else
carry =
'0';
}
}
if(add[
0] >
'9') {
add[
0]-=
10;
add.insert(
0,
1,
'1');
}
return add;
}
减法差的长度:number1和number2中长度最大的赋值就好了,最后若为1,就insert1number1和number2相差几位,在前面补0number2.insert(0, differenceInLength, '0'); // put zeros from left减法是要从高位借位(可以不用考虑0吧,反正小的话会借位,会+10)sub[i] = ((number1[i]-'0')-(number2[i]-'0')) + '0';除去最开始的0,erase,所以只需要最开始位不为0,以及最后长度要>=1
string BigInteger::subtract(string number1, string number2) {
string
sub = (number1.length()>number2.length())? number1 : number2;
int differenceInLength =
abs( (
int)(number1.size() - number2.size()) );
if(number1.size() > number2.size())
number2.insert(
0, differenceInLength,
'0');
else
number1.insert(
0, differenceInLength,
'0');
for(
int i=number1.
length()-
1; i>=
0; --i) {
if(number1[i] < number2[i]) {
number1[i] +=
10;
number1[i-
1]--;
}
sub[i] = ((number1[i]-'0')-(number2[i]-'0')) + '0';
}
while(
sub[0]=='0' && sub.length()!=1) // erase leading zeros
sub.erase(0,1);
return sub;
}
大于 逻辑就是不等于且不小于
bool BigInteger::
greater(BigInteger n1, BigInteger n2) {
return ! equals(n1, n2) && !
less(n1, n2);
}
等于 string相等就是的了且符号相等
bool BigInteger::equals(BigInteger n1, BigInteger n2) {
return n1
.getNumber() == n2
.getNumber()
&& n1
.getSign() == n2
.getSign()
}
小于先看符号,不同的话就是正的大符号相同,都是正,那个长哪个大,否则长度相同,直接比较string符号相同,都是负,那个长哪个小,否则长度相同,直接比较string
bool BigInteger::less(BigInteger n1, BigInteger n2) {
bool sign1 = n1.getSign();
bool sign2 = n2.getSign();
if(sign1 && ! sign2)
return true;
else if(! sign1 && sign2)
return false;
else if(! sign1) {
if(n1.getNumber().
length() < n2.getNumber().
length() )
return true;
if(n1.getNumber().
length() > n2.getNumber().
length() )
return false;
return n1.getNumber() < n2.getNumber();
}
else {
if(n1.getNumber().
length() > n2.getNumber().
length())
return true;
if(n1.getNumber().
length() < n2.getNumber().
length())
return false;
return n1.getNumber().compare( n2.getNumber() ) >
0;
}
}
转载请注明原文地址: https://ju.6miu.com/read-1125502.html