前言:
国庆前的好未来面试,让我写一个大数的乘法(字符串实现)。我Debug好久,竟然没有写出来。回来在自己电脑上两分钟就写出来了,感觉还是天天找工作,许久没有练手了,生疏了,何况还在Xcode上面。总结:代码必须天天写,要有良好的编程风格,在结构上、注释上、命名上需要加强。
类:
#pragma once
#ifndef _BIGINT_H
#define _BIGINT_H
#include <iostream>
const int N = 1024;
class BigInt {
friend std::ostream &operator<<(std::ostream &os, const BigInt &rhs);
public:
BigInt() :cData(nullptr), length(0),sign(1){}
BigInt(int im);
BigInt(const char *cp);
BigInt(const char *cp,int len);
~BigInt();
BigInt(const BigInt &rhs);
BigInt& operator=(const BigInt &rhs);
BigInt& operator+();
BigInt& operator-();
BigInt& operator++();
BigInt& operator--();
BigInt operator++(int);
BigInt operator--(int);
BigInt& operator=(const int &im);
BigInt& operator+=(const BigInt &rhs);
BigInt& operator-=(const BigInt &rhs);
BigInt& operator*=(const BigInt &rhs);
BigInt& operator/=(const BigInt &rhs);
char &operator[](const size_t &pos)
{
return cData[pos];
}
const char & operator[](const size_t &pos) const
{
return cData[pos];
}
const size_t getLen() const
{
return length;
}
const int & getSign() const
{
return sign;
}
private:
char *cData;
size_t length;
int sign;//通过此处可以改善实现正(1)负(-1)
};
//实现要与声明分离。
BigInt operator+(const BigInt &lhs, const BigInt &rhs);
BigInt operator-(const BigInt &lhs, const BigInt &rhs);
BigInt operator*(const BigInt &lhs, const BigInt &rhs);
BigInt operator/(const BigInt &lhs, const BigInt &rhs);
bool operator<(const BigInt &lhs, const BigInt &rhs);
bool operator>(const BigInt &lhs, const BigInt &rhs);
bool operator<=(const BigInt &lhs, const BigInt &rhs);
bool operator>=(const BigInt &lhs, const BigInt &rhs);
bool operator==(const BigInt &lhs, const BigInt &rhs);
bool operator!=(const BigInt &lhs, const BigInt &rhs);
#endif
//_BIGINT_H
乘法:
BigInt & BigInt::operator*=(const BigInt & rhs)
{
// TODO: 在此处插入 return 语句
char *rp = rhs.cData, *lp = this->cData;
int rLen = rhs.length, lLen = this->length;
int len = N;
char *cp = new char[len+1 ];
for (int i = 0;i < len;++i) cp[i] = '0';
cp[len] = '\0';
for (int rPos = rLen - 1, cPos = len - 1;rPos >= 0;--rPos, --cPos)//cpos跟随rpos变化
{
int k = cPos, c = 0;
for (int lPos = lLen - 1;lPos >= 0;--lPos,--k)
{
int rVal = rp[rPos] - '0';
int lVal = lp[lPos] - '0';
int cVal = cp[k] - '0' + rVal*lVal + c;
cp[k]=(cVal % 10)+'0';
c = cVal / 10;
}
}
delete[] this->cData;
int start = 0;
while (cp[start] == '0') ++start;
char *res = new char[len - start + 1];
length = len - start;
int i = 0;
while (start < len)
{
res[i++] = cp[start++];
}
res[i] = '\0';
cData = res;
delete[] cp;
sign *= rhs.sign;
return *this;
}
除法:
BigInt & BigInt::operator/=(const BigInt & rhs)
{
// TODO: 在此处插入 return 语句
try {
if (rhs == 0)
throw std::runtime_error("divider is zero.");
}catch (std::runtime_error err) {
std::cout << err.what() << std::endl;
*this = 0;
return *this;
}
char *rp = rhs.cData, *lp = this->cData;
int rLen = rhs.length, lLen = this->length;
if (lLen == rLen)
{
char *cp = new char[2];
if (*this>rhs)
{
int val = (lp[0]-'0') / (rp[0]-'0');
BigInt temp{ val };
if (temp*rhs > *this)
{
cp[0] = val - 1 + '0';
}
else
{
cp[0] = val+'0';
}
}
else if(*this<rhs)
{
cp[0] = '0';
}
else
{
cp[0] = '1';
}
cp[1] = '\0';
this->cData = cp;
this->length = 1;
}
else
{
int len = lLen-rLen+1;
char *cp = new char[len + 1];
for (int i = 0;i < len;++i) cp[i] = '0';
cp[len] = '\0';
BigInt mod{ "0" };
BigInt temp(lp, rLen);
BigInt t = temp / rhs;
cp[0] = t.cData[0];
mod = temp - t*rhs;
for (int i = 1,lPos = rLen;lPos<lLen;++i, ++lPos)
{
BigInt temp1(lp + lPos,1);
mod *= {"10"};
temp1 += mod;
BigInt t=temp1 / rhs;//递归
cp[i] = t.cData[0];
mod = temp1 - t*rhs;
}
this->cData = cp;
this->length = len;
}
delete[] lp;
sign *= rhs.sign;
return *this;
}
详细代码:
参见github:
点击打开链接