C++:大数加减实现,mstring类的实现

10_21

大数加减:
bignum.h

#pragma once
#ifndef BIG_NUM_H
#define BIG_NUM_H
#include<iostream>
#include<string>
using namespace std;

class BigNum
{
    
    
public:
	BigNum(int num = 0);//空的构造函数
	BigNum(const string& str);//string构造
	BigNum(const BigNum& src);//拷贝构造
	BigNum& operator=(const BigNum& src);//等号运算符重载,不用析构,系统会自动调用析构函数

	BigNum operator+(const BigNum& src);//加法运算符重载
	BigNum operator-(const BigNum& src);//减法运算符重载

	BigNum& operator++();//前置++
	BigNum operator++(int);//后置++

	bool operator&&(const BigNum& bignum);
	friend ostream& operator<<(ostream& out, const BigNum& src);
private:
	char int_to_char(int num)
	{
    
    
		char err[] = {
    
     '0','1','2','3','4','5','6','7','8','9' };
		return err[num];
	}

	int char_to_int(char c)
	{
    
    
		char err[] = {
    
     '0','1','2','3','4','5','6','7','8','9' };
		for (int i = 0; i < sizeof(err) / sizeof(err[0]); i++)
		{
    
    
			if (err[i] == c)
			{
    
    
				return i;
			}
		}

		return -1;
	}

	string _num;
};


#endif

bignum.cpp

#include"bignum.h"

BigNum::BigNum(int num)
{
    
    
	char c;
	int val;

	while (num != 0)
	{
    
    
		val = num % 10;//最低位
		c = int_to_char(val);
		_num.push_back(c);//尾插法插入
		num /= 10;//最高位
	}
}

BigNum::BigNum(const string& str)
{
    
    
	for (int i = str.size() - 1; i >= 0; i--)
	{
    
    
		_num.push_back(str[i]);
	}
}

BigNum::BigNum(const BigNum& src)//string的底层是一个字符串,所以不用clear
{
    
    
	_num = src._num;
}

BigNum& BigNum::operator=(const BigNum& src)
{
    
    
	_num = src._num;
	return *this;
}

BigNum BigNum::operator+(const BigNum& src)
{
    
    
	int sum = 0;
	int val = 0;
	int flag = 0;

	BigNum tmp;

	int i = 0;
	//将长度相同的部分先加起来
	for (; i < _num.size() && i < src._num.size(); i++)
	{
    
    
		sum = char_to_int(_num[i]) + char_to_int(src._num[i]) + flag;
		val = sum % 10;
		flag = sum / 10;
		tmp._num.push_back(int_to_char(val));
	}


	//找出当前还没有计算完的是哪个大数
	const string* p = NULL;
	if (i < _num.size())
	{
    
    
		p = &_num;
	}
	else if (i < src._num.size())
	{
    
    
		p = &src._num;
	}
	else
	{
    
    
		//如果都走完了,看一下是否还有进位没有放进去
		if (flag != 0)
		{
    
    
			tmp._num.push_back(int_to_char(flag));
		}
	}

	//将没有走完的大数继续进行运算
	for (; NULL != p && i < p->size(); i++)
	{
    
    
		sum = char_to_int((*p)[i]) + flag;
		val = sum % 10;
		flag = sum / 10;
		tmp._num.push_back(int_to_char(val));
	}

	//走完了之后,看一下是否还有进位没有放进去
	if (flag != 0)
	{
    
    
		tmp._num.push_back(int_to_char(flag));
	}

	return tmp;
}



BigNum BigNum::operator-(const BigNum& src) 
{
    
     
	return *this;
}

BigNum& BigNum::operator++()//前置++
{
    
    
	int sum = 0;
	int flag = 0;
	int val = 0;

	if (_num.empty())
	{
    
    
		_num.push_back('0');
	}

	//将个位的数字+1
	sum = char_to_int(_num[0]) + 1;
	val = sum % 10;
	flag = sum / 10;
	_num[0] = int_to_char(val);


	//如果存在进位的情况
	int i = 1;
	while (flag != 0 && i < _num.size())
	{
    
    
		sum = char_to_int(_num[i]) + flag;
		val = sum % 10;
		flag = sum / 10;
		_num[i] = int_to_char(val);
		i++;
	}

	//如果到最后依然存在进位
	if (flag != 0)
	{
    
    
		_num.push_back(int_to_char(flag));
	}

	return *this;
}

BigNum BigNum::operator++(int)//后置++
{
    
    
	BigNum tmp = *this;
	int sum = 0;
	int flag = 0;
	int val = 0;

	if (_num.empty())
	{
    
    
		_num.push_back('0');
	}

	//将个位的数字+1
	sum = char_to_int(_num[0]) + 1;
	val = sum % 10;
	flag = sum / 10;
	_num[0] = int_to_char(val);


	//如果存在进位的情况
	int i = 1;
	while (flag != 0 && i < _num.size())
	{
    
    
		sum = char_to_int(_num[i]) + flag;
		val = sum % 10;
		flag = sum / 10;
		_num[i] = int_to_char(val);
		i++;
	}

	//如果到最后依然存在进位
	if (flag != 0)
	{
    
    
		_num.push_back(int_to_char(flag));
	}

	return tmp;
}

//  0  && 0   1&&0     1 && 1
bool BigNum::operator&&(const BigNum& bignum)
{
    
    
	//两个中有一个空的或者全为空
	if (_num.empty() || bignum._num.empty())
	{
    
    
		return false;
	}
	//"0"   有一个数字不为空,但是只有一个0在里面
	if (_num.size() == 1 && _num[0] == '0')
	{
    
    
		return false;
	}

	//有一个不为空,但是只有一个0在里面
	if (bignum._num.size() == 1 && bignum._num[0] == '0')
	{
    
    
		return false;
	}

	return true;
}

ostream& operator<<(ostream& out, const BigNum& src)
{
    
    
	for (int i = src._num.size() - 1; i >= 0; i--)
	{
    
    
		cout << src._num[i];
	}
	cout << endl;
	return out;
}

main(bignum):测试用例

#include<iostream>
#include"bignum.h"
using namespace std;

/*
* 刷题
* 要求每周两道  ---- 发到邮箱 --- word ----- 每周周一交
*
*
* 1.BigNum  代码实现
* 2.Mstring  仿写string
*/
int main()
{
    
    
	BigNum b1(8789);
	BigNum b2("95779");

	BigNum b3 = b1 + b2;
	cout << b3 << endl;


	return 0;
}

仿写库中的Mstring类

mstring.h

#ifndef MSTRING_H
#define MSTRING_H
#include<iostream>
using namespace std;

#define DEFEALT_LEN 10


class Mstring
{
    
    
public:
	Mstring(const char* str = NULL);
	Mstring(const Mstring& src);
	Mstring& operator=(const Mstring& src);
	~Mstring();

	void push_back(char c);
	void pop_back();
	char back()const;//获取最后一个元素
	char front()const;//获取第一个元素
	bool empty()const;//是否为空
	int size()const;//计算长度

	Mstring operator+(const Mstring& str)const;
	char& operator[](int pos);//中括号运算符重载
	char operator[](int pos)const;

	friend ostream& operator<<(ostream& out, const Mstring& src);
	friend istream& operator>>(istream& in, Mstring& src);
private:
	bool full()const;
	void revert();

	char* _str;
	int _len;//当前空间总长度
	int _val_len;//已经占用的长度,试即数据数量
};

#endif#pragma once

mstring.cpp

#include"mstring.h"

Mstring::Mstring(const char* str)
{
    
    
	//当为空的时候,置为0
	if (NULL == str)
	{
    
    
		_len = DEFEALT_LEN;
		_val_len = 0;
		_str = new char[_len];
		memset(_str, 0, _len);
		return;
	}
	//当不为空的时候,
	_val_len = strlen(str);
	_len = _val_len + 1;//有\0,所以长度+1
	_str = new char[_len];//申请空间
	memset(_str, 0, _len);//全部设置为0
	//数据依次拷贝进去
	for (int i = 0; i < _val_len; i++)
	{
    
    
		_str[i] = str[i];
	}
}
//拷贝构造
Mstring::Mstring(const Mstring& src)
{
    
    
	_val_len = strlen(src._str);
	_len = _val_len + 1;
	_str = new char[_len];
	memset(_str, 0, _len);

	for (int i = 0; i < _val_len; i++)
	{
    
    
		_str[i] = src._str[i];
	}
}


Mstring& Mstring::operator=(const Mstring& src)
{
    
    
	//防止自赋值
	if (&src == this)
	{
    
    
		return *this;
	}

	delete[]_str;//删除原来的值,防止内存泄漏
	//防止浅拷贝
	_val_len = strlen(src._str);
	_len = _val_len + 1;
	_str = new char[_len];
	memset(_str, 0, _len);

	for (int i = 0; i < _val_len; i++)
	{
    
    
		_str[i] = src._str[i];
	}
	return *this;
}

Mstring::~Mstring()
{
    
    
	delete[]_str;
}

void Mstring::push_back(char c)
{
    
    
	//判断当前空间是否占满
	if (full())
	{
    
    
		revert();//扩容
	}

	_str[_val_len] = c;
	_val_len++;
}

void Mstring::pop_back()
{
    
    
	if (empty())
	{
    
    
		return;
	}

	_val_len--;
}

char Mstring::back()const
{
    
    
	if (empty())
	{
    
    
		return 0;
	}

	return _str[_val_len - 1];
}

char Mstring::front()const
{
    
    
	if (empty())
	{
    
    
		return 0;
	}

	return _str[0];
}

bool Mstring::empty()const//判空
{
    
    
	return _val_len == 0;
}

Mstring Mstring::operator+(const Mstring& str)const
{
    
    
	char* p;
	int len = _val_len + str._val_len + 1;
	p = new char[len];
	memset(p, 0, len);

	//进行数据拷贝-----将两个字符串的数据拼接起来
	int i = 0;
	for (; i < _val_len; i++)
	{
    
    
		p[i] = _str[i];
	}

	for (int j = 0; j < str._val_len; j++, i++)
	{
    
    
		p[i] = str._str[j];
	}

	return p;
}

char& Mstring::operator[](int pos)
{
    
    
	return _str[pos];
}

char Mstring::operator[](int pos)const
{
    
    
	return _str[pos];
}

bool Mstring::full()const
{
    
    
	return _val_len == _len - 1;
}

void Mstring::revert()
{
    
    
	_len = _len << 1;

	char* p = new char[_len];
	memset(p, 0, _len);

	for (int i = 0; i < _val_len; i++)
	{
    
    
		p[i] = _str[i];
	}

	delete[]_str;
	_str = p;
}

int Mstring::size()const
{
    
    
	return _val_len;
}

ostream& operator<<(ostream& out, const Mstring& src)//常对象只能调用常方法
{
    
    
	for (int i = 0; i < src.size(); i++)
	{
    
    
		out << src[i];
	}
	out << endl;
	return out;
}

istream& operator>>(istream& in, Mstring& src)
{
    
    
	char tmp[1024];
	in >> tmp;

	src = tmp;
	return in;
}

main(mstring).cpp

#include<iostream>
#include"bignum.h"
#include"mstring.h"
using namespace std;

/*
* 刷题
* 要求每周两道  ---- 发到邮箱 --- word ----- 每周周一交
*
* 1.BigNum  代码实现
* 2.Mstring  仿写string
*
*
*/
int main()
{
    
    
	BigNum b1(8789);
	BigNum b2("95779");

	BigNum b3 = b1 + b2;
	cout << b3 << endl;

	string s = "qqqq";
	string s1 = "eee";
	string s3 = s1 + s;
	s.push_back('o');
	for (int i = 0; i < s.size(); i++)
	{
    
    
		cout << s[i] << " ";
		//s[i] = 'y';
		//cout << endl;
	}
	s.pop_back();
	s.empty();

	s.back();
	s.front();
	cout << endl;
	cout << "================================" << endl;
	Mstring str1;
	cout << str1 << endl;

	Mstring str2("1234567");
	cout << str2 << endl;
	str2.push_back('9');
	cout << str2 << endl;

	cin >> str1;
	cout << str1 << endl;

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_48580892/article/details/120973102