|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 bin554385863 于 2020-1-7 04:20 编辑
#include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.cpp"
lnum fact(const lnum &n)
{
lnum fact = "1";
for (lnum i = "1"; i <= n; i++)
{
fact *= i;
}
return fact;
}
int main(int argc, char const *argv[])
{
lnum a = "1";
for (lnum i = "10"; i != "110"; i += "10")
{
std::cout << i<<"! = "<<fact(i) << std::endl;
}
return 0;
}
=============================================================================
Microsoft Windows [版本 10.0.18363.535]
(c) 2019 Microsoft Corporation。保留所有权利。
E:\Users\admin\Documents\VScode\Code>c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-bln4vusc.bgf --stdout=Microsoft-MIEngine-Out-pkxxzoxc.0jt --stderr=Microsoft-MIEngine-Error-tn53w3yl.5hv --pid=Microsoft-MIEngine-Pid-ddmgmwek.eog --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
10! = 3628800
20! = 2432902008176640000
30! = 265252859812191058636308480000000
40! = 815915283247897734345611269596115894272000000000
50! = 30414093201713378043612608166064768844377641568960512000000000000
60! = 8320987112741390144276341183223364380754172606361245952449277696409600000000000000
70! = 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000
80! = 71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000
90! = 1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
E:\Users\admin\Documents\VScode\Code>
完整代码
当字符串出现其他非数字字符时(有效的负号和小数点除外)全部按"0"处理.
代码不能识别顺序错误的数字字符串,如"0005000"这样的数字字符串,请输入正确的数字字符串如:"1365458", "-0.1234566"等等(可以实现在构造对象时清除无效零的功能,相应函数已经写好,但这样会在计算带小数位的乘法时造成额外的逻辑判断)
已经重载输出流符号<<和输入流符号>>,可以向基础类型一样使用cout/cin进行输入输出.
lnum.cpp
- #ifndef LNUM_H
- #define LNUM_H
- #include <iostream>
- #include <string>
- #include <vector>
- using std::istream;
- using std::ostream;
- using std::string;
- using std::vector;
- class lnum
- {
- struct ndata
- {
- int sign;
- string nstr;
- vector<int> nvec;
- size_t isize, dsize;
- };
- struct align
- {
- vector<int> first, second;
- };
-
- private:
- static size_t pre;
- ndata data;
- //(0)判断是否含有小数点
- const bool hasDecPoint(const string &s) const;
- //(1)判断字符串是否有效
- const bool isInvalidStr(const string &s) const;
- //(2)判断字符串元素是否全为零
- const bool isStrElemAllZero(const string &s) const;
- //(3)清除无效的零
- const string clearInvalidZero(const string &s) const;
- //(4)转换数组
- const vector<int> strToVec(const string &s) const;
- //(-4)转换字符串
- const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
- //(5)提取信息
- const ndata getInfo(const string &s) const;
- //(6)小数位对齐
- align dAlign(const lnum &l) const;
- //(7)整体对齐
- align wAlign(const lnum &l) const;
- //(8)满十进一
- void carry(vector<int> &v) const;
- //(9)借一补十
- void borrow(vector<int> &v) const;
- //(10)输出设置
- const string setPrint() const;
- //(11)lnum*n
- const lnum operator*(const int &n) const;
- public:
- lnum(const char *cstr = "0") : data(getInfo(cstr))
- {
- }
- lnum(const string &s):data(getInfo(s)){}
- void showinfo() const;
- static void setprecision(const size_t p);
- //(1)>号
- const bool operator>(const lnum &l) const;
- //(2)==
- const bool operator==(const lnum &l) const;
- //(3)>=
- const bool operator>=(const lnum &l) const;
- //(4)<
- const bool operator<(const lnum &l) const;
- //(5)<=
- const bool operator<=(const lnum &l) const;
- //(5)!=
- const bool operator!=(const lnum &l) const;
- //(6)+
- const lnum operator+(const lnum &l) const;
- //(7)-反转正负
- const lnum operator-() const;
- //(7.5)-
- const lnum operator-(const lnum &l) const;
- //(8)+=
- const lnum &operator+=(const lnum &l);
- //(9)++
- const lnum &operator++(const int i);
- //(10)-=
- const lnum &operator-=(const lnum &l);
- //(11)--
- const lnum &operator--(const int i);
- //(12)lnum*lnum
- const lnum operator*(const lnum &l) const;
- //(10)*=
- const lnum &operator*=(const lnum &l);
- //(F)<<
- friend ostream &operator<<(ostream &os, const lnum &l);
- //(F)>>
- friend istream &operator>>(istream &is, lnum &l);
- ~lnum(){}
- };
- size_t lnum::pre = 6;
- #endif
复制代码
方法实现
lnum.cpp
- #include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
- //(0)判断是否含有小数点
- const bool lnum::hasDecPoint(const string &s) const
- {
- return int(s.find('.')) > -1 ? true : false;
- }
- //(1)判断字符串是否有效
- const bool lnum::isInvalidStr(const string &s) const
- {
- bool f = true;
- string str = s;
- if (str[0] == '-')
- {
- str.erase(0, 1);
- }
- if (!hasDecPoint(str))
- {
- for (char c : str)
- {
- if (!isdigit(c))
- {
- f = false;
- break;
- }
- }
- }
- else
- {
- size_t dpinx = str.find('.');
- f = (dpinx == 0) || (dpinx == (str.size() - 1)) || (dpinx != str.rfind('.')) ? false : true;
- str.erase(dpinx, 1);
- for (char c : str)
- {
- if (!isdigit(c))
- {
- f = false;
- break;
- }
- }
- }
- return f;
- }
- //(2)判断字符串元素是否全为零
- const bool lnum::isStrElemAllZero(const string &s) const
- {
- string str = s;
- str[0] == '-' ? str.erase(0, 1) : str;
- hasDecPoint(str) || false ? str.erase(str.find('.'), 1) : str;
- return str == string(str.size(), '0') ? true : false;
- }
- //(3)清除无效的零
- const string lnum::clearInvalidZero(const string &s) const
- {
- string str = s;
- if (isInvalidStr(s))
- {
- size_t i = 0;
- if (str[0] == '-')
- {
- str.erase(0, 1);
- }
- if (!hasDecPoint(s))
- {
- size_t sz = str.size();
- while (i != sz)
- {
- if (str[i] != '0')
- {
- break;
- }
- i++;
- }
- if (i == sz)
- {
- str.erase(0, i - 1);
- }
- else if (i > 0)
- {
- str.erase(0, i);
- }
- }
- else
- {
- i = 0;
- while (str[i] != '.')
- {
- if (str[i] != '0')
- {
- break;
- }
- i++;
- }
- if (i == str.find('.'))
- {
- str.erase(0, i - 1);
- }
- else if (i > 0)
- {
- str.erase(0, i);
- }
- i = str.size() - 1;
- while (str[i] != '.')
- {
- if (str[i] != '0')
- {
- break;
- }
- i--;
- }
- if (i == str.find('.'))
- {
- str.erase(i);
- }
- else if (i < str.size() - 1)
- {
- str.erase(i + 1);
- }
- }
- }
- if (s[0] == '-' && str != "0")
- {
- str.insert(0, 1, '-');
- }
- return str;
- }
- //(4)转换数组
- const vector<int> lnum::strToVec(const string &s) const
- {
- vector<int> vint;
- string str = s;
- str[0] == '-' ? str.erase(0, 1) : str;
- hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
- for (char c : str)
- {
- vint.push_back(c - 48);
- }
- return vint;
- }
- //(-4)转换字符串
- const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
- {
- string str;
- for (int i : vint)
- {
- str.push_back(i + 48);
- }
- if (str != "0")
- {
- dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
- sgn == -1 ? str.insert(0, 1, '-') : str;
- }
- return str;
- }
- //(5)提取信息
- const lnum::ndata lnum::getInfo(const string &s) const
- {
- ndata ndt = {0, "0", {0}, 1, 0};
- if (isInvalidStr(s))
- {
- ndt.nstr = s;
- ndt.sign = ndt.nstr != "0" ? (ndt.nstr[0] == '-' ? -1 : 1) : 0;
- ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
- ndt.nvec = strToVec(ndt.nstr);
- ndt.isize = ndt.nvec.size() - ndt.dsize;
- }
- return ndt;
- }
- //(6)小数位对齐
- lnum::align lnum::dAlign(const lnum &l) const
- {
- align agn;
- vector<int> &f = agn.first, &s = agn.second;
- f = data.nvec;
- s = l.data.nvec;
- const size_t &fds = data.dsize, &sds = l.data.dsize;
- fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
- return agn;
- }
- //(7)整体对齐
- lnum::align lnum::wAlign(const lnum &l) const
- {
- align &&agn = this->dAlign(l);
- vector<int> &f = agn.first, &s = agn.second;
- const size_t &fws = data.isize, &sws = l.data.isize;
- fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
- return agn;
- }
- //(8)满十进一
- void lnum::carry(vector<int> &v) const
- {
- v.insert(v.begin(), 1, 0);
- const size_t s = v.size();
- for (size_t i = s - 1; i != 0; i--)
- {
- int t = v[i];
- v[i] = t % 10;
- v[i - 1] += t / 10;
- }
- if (v[0] == 0)
- {
- v.erase(v.begin(), v.begin() + 1);
- }
- }
- //(9)借一补十
- void lnum::borrow(vector<int> &v) const
- {
- const size_t s = v.size();
- for (size_t i = 1; i < s; i++)
- {
- v[i - 1] -= 1;
- v[i] += 10;
- }
- }
- //(10)输出设置
- const string lnum::setPrint() const
- {
- const size_t &tds = data.dsize;
- string str = data.nstr;
- if (pre == 0)
- {
- if (tds != 0)
- {
- str.erase(str.find('.'));
- }
- }
- else if (tds > pre)
- {
- str.erase(str.size() - (tds - pre));
- }
- return clearInvalidZero(str);
- }
- //(11)lnum*n
- const lnum lnum::operator*(const int &n) const
- {
- vector<int> t = data.nvec;
- for (int &i : t)
- {
- i *= n;
- }
- carry(t);
- lnum r = vecToStr(t, data.sign, data.dsize);
- return r;
- }
- //==========================================================================
- //(0)显示信息
- void lnum::showinfo() const
- {
- std::cout << "正/负/零: " << data.sign << "\n"
- << "原始数字: " << data.nstr << "\n"
- << "数组元素: ";
- for (int i : data.nvec)
- {
- std::cout << i << " ";
- }
- std::cout << std::endl;
- std::cout << "整数位数: " << data.isize << "\n"
- << "小数位数: " << data.dsize << std::endl;
- }
- void lnum::setprecision(const size_t p)
- {
- pre = p;
- }
- //(1)>号
- const bool lnum::operator>(const lnum &l) const
- {
- bool f = true;
- const int &tsgn = data.sign, &lsgn = l.data.sign;
- if (tsgn < lsgn)
- {
- f = false;
- }
- else if (tsgn == lsgn)
- {
- const align &agn = this->wAlign(l);
- f = agn.first > agn.second;
- if (tsgn == -1)
- {
- f = !f;
- }
- }
- return f;
- }
- //(2)==
- const bool lnum::operator==(const lnum &l) const
- {
- return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
- }
- //(3)>=
- const bool lnum::operator>=(const lnum &l) const
- {
- return (*this > l) || (*this == l);
- }
- //(4)<
- const bool lnum::operator<(const lnum &l) const
- {
- return !(*this >= l);
- }
- //(5)<=
- const bool lnum::operator<=(const lnum &l) const
- {
- return !(*this > l);
- }
- //(5.5)!=
- const bool lnum::operator!=(const lnum &l) const
- {
- return !(*this == l);
- }
- //(6)+
- const lnum lnum::operator+(const lnum &l) const
- {
- lnum r;
- if (*this != (-l))
- {
- align agn = this->wAlign(l);
- vector<int> &fst = agn.first,
- &sec = agn.second,
- &greater = fst >= sec ? fst : sec,
- &less = sec <= fst ? sec : fst;
- const int &tsgn = data.sign,
- &lsgn = l.data.sign;
- const size_t &sz = fst.size();
- for (size_t i = 0; i < sz; i++)
- {
- greater[i] += (lsgn * tsgn) * less[i];
- }
- int sgn = 1;
- if (tsgn == lsgn)
- {
- sgn = tsgn;
- }
- else if (tsgn != lsgn)
- {
- sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
- }
- if (tsgn * lsgn == -1)
- {
- borrow(greater);
- }
- carry(greater);
- size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
- r = vecToStr(greater, sgn, dsz);
- }
- return r;
- }
- //(7)-反转正负
- const lnum lnum::operator-() const
- {
- lnum r = *this;
- if (data.sign != 0)
- {
- r.data.sign = -data.sign;
- r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
- }
- return r;
- }
- //(7.5)-
- const lnum lnum::operator-(const lnum &l) const
- {
- return *this + (-l);
- }
- //(8)+=
- const lnum &lnum::operator+=(const lnum &l)
- {
- return *this = *this + l;
- }
- //(9)++
- const lnum &lnum::operator++(const int i)
- {
- return *this = *this + "1";
- }
- //(10)-=
- const lnum &lnum::operator-=(const lnum &l)
- {
- return *this = *this + (-l);
- }
- //(11)--
- const lnum &lnum::operator--(const int i)
- {
- return *this = *this + "-1";
- }
- //(12)lnum*lnum
- const lnum lnum::operator*(const lnum &l) const
- {
- lnum r;
- const int &tsgn = data.sign,
- &lsgn = l.data.sign;
- if (tsgn * lsgn == 0)
- {
- r = "0";
- }
- else
- {
- const vector<int> &tvec = data.nvec,
- &lvec = l.data.nvec;
- const size_t &tsz = data.dsize,
- &lsz = l.data.dsize,
- &tvsz = tvec.size(),
- &lvsz = lvec.size(),
- &shrtsz = tvsz <= lvsz ? tvsz : lvsz;
- lnum loong = tvsz >= lvsz ? *this : l;
- const vector<int> &shrtv = lvsz <= tvsz ? lvec : tvec;
- vector<int> &lovec = loong.data.nvec,
- &rvec = r.data.nvec;
- for (size_t i = shrtsz - 1; i != -1; i--)
- {
- r += loong * shrtv[i];
- if (i > 0)
- {
- lovec.push_back(0);
- }
- }
- r = vecToStr(rvec, tsgn * lsgn, tsz + lsz);
- }
- return r;
- }
- //(10)*=
- const lnum &lnum::operator*=(const lnum &l)
- {
- return *this = *this * l;
- }
- //(F)<<
- ostream &operator<<(ostream &os, const lnum &l)
- {
- os << l.setPrint();
- return os;
- }
- //(F)>>
- istream &operator>>(istream &is, lnum &l)
- {
- string str;
- (std::cin >> str).get();
- l = str;
- return is;
- }
复制代码 |
|