第2题:设计一个循环链表,用来表示大整数

 链表的头结点值为-1,其余结点依次存放数据,各结点最多放四位整数,如下图表示233238766:

 利用上述数据结构解决大整数的表示,以及加法、减法运算(用两个链表表示操作数)。
 将上述数据结构应用于10位以上求素数问题和阶乘问题。
在这里插入图片描述

用链表实现判断素数实在太蠢了

把链表中的存的数转化成longlong类型
然后运用Miller_Rabbin算法进行判断
相关算法可以参考
Miller_Rabbin

直接上代码
GreatInt.h
#ifndef GREATINT
#define GREATINT
#include <string>

using namespace std;

typedef struct queue {
	int i;
	queue* next;
}*Queue;

class GreatInt {
public:
	GreatInt(string nums = "");			//用字符串进行构造,默认构造函数
	GreatInt(const GreatInt& a);		//拷贝构造函数
	~GreatInt();	
	friend ostream& operator<<(ostream& os, const GreatInt& rhs);
	GreatInt operator+(const GreatInt& rhs) const;		//减法运算
	GreatInt operator-(const GreatInt& rhs) const;		//加法运算
	const GreatInt& factorial(int nums);				//阶乘运算
private:
	int compare(const GreatInt& rhs) const;			//进行比较
	string add(const GreatInt& lhs, const GreatInt& rhs) const;			//辅助加减法运算
	string min(const GreatInt& lhs, const GreatInt& rhs) const;
	void multiply(const int n);							//辅助阶乘运算
	bool signal;
	Queue head;
	Queue tail;
};

#endif
GreatInt.cpp
#include "GreatInt.h"
#include <iostream>
#include <malloc.h>
#include <stack>

using namespace std;

GreatInt::GreatInt(string nums) {
	head = (Queue)malloc(sizeof(*head));
	head->i = -1;
	signal = false;						//正负号
	int length = nums.size();
	if (!length) {						//默认构造一个空的对象
		head->next = head;
		tail = head;
		signal = false;
		return;
	}

	if (nums[0] == '-')					//正负号
	{
		signal = true;
	}

	Queue current = head;
	while (length > 0 + signal) {
		string temp;
		if (length >= 4 + signal) {		//四位一组进行赋值
			temp = string(nums, length - 4, 4);
		}
		else {
			temp = string(nums, 0 + signal, length - signal);
		}
		Queue tempn = (Queue)malloc(sizeof(*tempn));
		tempn->i = stoi(temp);
		current->next = tempn;
		current = current->next;
		length -= 4;
	}
	current->next = head;
	tail = current;
}

GreatInt::~GreatInt() {
	Queue current = head;
	tail->next = NULL;
	while (current) {
		head = head->next;
		free(current);
		current = head;
	}
}

GreatInt::GreatInt(const GreatInt& a) {
	head = (Queue)malloc(sizeof(*head));
	head->i = -1;
	Queue current = head;

	Queue pro = (a.head)->next;
	while (pro != a.head)				//将链表从头开始深copy
	{
		Queue temp = (Queue)malloc(sizeof(*temp));
		temp->i = pro->i;
		current->next = temp;
		current = current->next;
		pro = pro->next;
	}

	current->next = head;
	tail = current;
	
	signal = a.signal;
}

GreatInt GreatInt::operator+(const GreatInt& rhs) const
{
	string result;
	bool check = false;
	if (this->signal == rhs.signal) {		//同号直接相加,再判断正负号
		result = add(*this, rhs);
		if (this->signal == true)
			check = true;
	}
	else {
		if (this->signal == false)			//异号正的减去负数的绝对值
			result = min(*this, rhs);
		else
			result = min(rhs, *this);
	}

	if (check) {
		result = "-" + result;
	}

	return GreatInt(result);
}

GreatInt GreatInt::operator-(const GreatInt& rhs) const
{
	string result;
	bool check = false;
	if (this->signal == rhs.signal) {			//同号则两数绝对值相减并判断正负号
		result = min(*this, rhs);
		if (this->signal == true)
			check = true;
	}
	else {
		result = add(*this, rhs);				//异号则两数绝对值相加并判断正负号
		if (this->signal == true)
			check = true;
	}

	if (check) {
		if (result[0] == '-') {
			result.erase(0);
		}
		else {
			result = "-" + result;
		}
	}
	return GreatInt(result);
}

string int_string(int i) {						//数字转化为四位字符串
	if (i >= 1000)
		return to_string(i);
	else if (i >= 100)
		return "0" + to_string(i);
	else if (i >= 10)
		return "00" + to_string(i);
	else if (i >= 0)
		return "000" + to_string(i);
	else
		return "0";
}
string GreatInt::add(const GreatInt& lhs, const GreatInt& rhs) const {		//绝对值相加
	int add_sum;
	int sign = 0;

	string result;
	Queue currentl = (lhs.head)->next;
	Queue currentr = (rhs.head)->next;
	while (currentl != lhs.head && currentr != rhs.head)
	{
		add_sum = currentl->i + currentr->i + sign;
		if (add_sum >= 10000)
			sign = 1;
		else
			sign = 0;
		add_sum %= 10000;
		result = int_string(add_sum) + result;
		currentl = currentl->next;
		currentr = currentr->next;
	}

	Queue pro = (currentl == lhs.head) ? currentr : currentl;
	Queue headcheck = (currentl == lhs.head) ? rhs.head : lhs.head;

	while (pro != headcheck)
	{
		result = int_string((pro->i + sign) % 10000) + result;
		sign = (pro->i + sign) / 10000;
		pro = pro->next;
	}

	if (sign == 1) {
		result = to_string(1) + result;
	}

	return result;
}

string GreatInt::min(const GreatInt& lhs, const GreatInt& rhs) const{			//绝对值相减
	int check = lhs.compare(rhs);
	Queue currentl, currentr;
	Queue endl, endr;
	bool zf = 0;
	string result;
	if (check == 0) {
		return "0";
	}
	else if(check == 1) {
		currentl = lhs.head->next;
		endl = lhs.head;
		currentr = rhs.head->next;;
		endr = rhs.head;
	}
	else {
		currentl = rhs.head->next;
		endl = rhs.head;
		currentr = lhs.head->next;
		endr = lhs.head;
		zf = 1;
	}

	int min_sum;
	int sign = 0;
	while (currentl != endl && currentr != endr)
	{
		min_sum = currentl->i - currentr->i + sign;
		if (min_sum < 0) {
			sign = -1;
			min_sum += 10000;
		}
		else
			sign = 0;
		result = int_string(min_sum) + result;
		currentl = currentl->next;
		currentr = currentr->next;
	}

	while (currentl != endl)
	{
		if ((currentl->i + sign) < 0) {
			sign = -1;
			result = int_string(currentl->i + sign + 10000) + result;
		}
		else {
			result = int_string(currentl->i + sign) + result;
			sign = 0;
		}
		currentl = currentl->next;
	}

	if (zf == 1) {
		result =  "-" + result;
	}

	return result;
}


int GreatInt::compare(const GreatInt& rhs) const{			//判断两数绝对值大小
	Queue currentl = this->head->next;
	Queue currentr = (rhs.head)->next;
	stack<short> store;

	while (currentl != this->head && currentr != rhs.head)
	{
		if (currentl->i == currentr->i) {
			store.push(0);
		}
		else if (currentl->i > currentr->i) {
			store.push(1);
		}
		else
			store.push(-1);
		currentl = currentl->next;
		currentr = currentr->next;
	}
	
	if (currentl != this->head) {
		return 1;
	}
	else if (currentr != rhs.head) {
		return -1;
	}

	while (1) {
		if (store.size() == 0)
			return 0;
		if (store.top() == 0)
		{
			store.pop();
		}
		else if (store.top() == 1) {
			return 1;
		}
		else if (store.top() == -1) {
			return -1;
		}
	}
}


ostream& operator<<(ostream& os, const GreatInt& rhs) {			//友好输出
	string result;
	Queue current = rhs.head->next;
	while (current != rhs.head) {
		if (current->next == rhs.head) {
			result = to_string(current->i) + result;
			break;
		}
		result = int_string(current->i) + result;
		current = current->next;
	}
	if (rhs.signal == true)
		result = "-" + result;
	os << result;
	return os;
}

void GreatInt::multiply(const int n) {							//乘法
	Queue current = this->head->next;
	int sign = 0;
	while (current != head) {
		current->i *= n;
		current->i += sign;
		sign = current->i / 10000;
		current->i %= 10000;
		if (current->next == head) {
			break;
		}
		else {
			current = current->next;
		}
	}
	while(sign > 0) {
		Queue temp = (Queue)malloc(sizeof(*temp));
		temp->i = sign % 10000;
		temp->next = head;
		current->next = temp;
		current = current->next;
		sign /= 10000;
	}
	tail = current;
	tail->next = head;
}

const GreatInt& GreatInt::factorial(int nums) {					//阶乘
	Queue current;
	if (head->next == head) {
		head->next = (Queue)malloc(sizeof(*head));
		head->next->next = head;
	}
	else {
		tail->next = NULL;
		current = head->next->next;
		while (current) {
			head = head->next;
			free(current);
			current = head;
		}
	}
	current = head->next;
	current->i = 1;
	current->next = head;
	for (int j = nums; j > 0; --j)
	{
		this->multiply(j);
	}
	return *this;
}
main.cpp
#include <iostream>
#include "GreatInt.h"
#include <string>
using namespace std;

//类已经封装,直接使用即可
int main()
{
	string first;
	string second;
	cout << "Please enter two nums:" << endl;

	cout << "the first: ";
	cin >> first;
	cout << "the second: ";
	cin >> second;
	GreatInt one(first);			//使用构造函数进行封装
	GreatInt two(second);

	cout << endl;
	cout << "the result of (first + second)" << endl;
	cout << one + two << endl;		//加法运算

	cout << endl;
	cout << "the result of (first - second)" << endl;
	cout << one - two << endl;		//减法运算

	cout << endl;
	cout << "factorial 100:" << endl;
	GreatInt three;
	cout << three.factorial(100);	//运用成员函数进行100的阶乘运算

	return 0;
}
  • 11
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值