大数的运算实现(C++、字符串)、Git使用示例

1 篇文章 0 订阅

前言:

国庆前的好未来面试,让我写一个大数的乘法(字符串实现)。我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: 点击打开链接

测试:




Git:

1、初始化,创建本地仓库、文件添加:



2、提交:



3、远程仓库:可以命令创建,可以网页上创建。由于本次是网页上创建,添加了readme文件,导致本地与远程不一致,无法直接push(推送),只能先pull再push。



4、ok。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值