用双向循环链表实现长整数加减乘除(四则运算)——数据结构课程实践

要求:

任意长整数的输入输出格式为每 4位十进制数一组,组间用逗号分隔。设计程序,实现长整数四则运算。

【设计要求】

  (1)采用带头结点的双向循环链表存储结构,描述线性表的抽象数据类型。

(2)每个结点存放 4位十进制数,设计算法,实现任意长整数的加、减法运算(头结点可做符号位)。

(3) 选做内容:实现任意长整数的乘、除法运算。

定义:

1.定义双向循环链表的结点

// 定义链表节点结构
struct Node {
	int data;
	Node* next;
	Node* prev;
};

2.定义双向循环链表类class BigInt 

私有部分

private:
	Node* head; // 头结点
	bool isNegative; // 符号位
	

公有部分:

BigInt构造函数

public:
	BigInt() {
		head = new Node();
		head->data = 0;
		head->next = head;
		head->prev = head;
		isNegative = false;
	}

判断长正数是否为0

	//判断是否为0
    int isZero(){
	return (head->next->data==0);
    }

 在链表尾部插入数据

// 在链表尾部插入数据
	void InsertBack(int data) {
		Node* newNode = new Node();
		newNode->data = data;
		newNode->next = head;
		newNode->prev = head->prev;
		head->prev->next = newNode;
		head->prev = newNode;
	}

 移除链表开头多余的零值节点

void RemoveFrontZeros() {
		Node* currentNode = head->next;
		
		// 移动到第一个非零节点
		while (currentNode != head && currentNode->data == 0) {
			Node* temp = currentNode;
			currentNode = currentNode->next;
			currentNode->prev = head;
			head->next = currentNode;
			delete temp;
		}
	}

插入数据到链表头部

	// 插入数据到链表头部
	void InsertFront(int data) {
		Node* newNode = new Node();
		newNode->data = data;
		newNode->next = head->next;
		newNode->prev = head;
		head->next->prev = newNode;
		head->next = newNode;
	}
	

   从字符串构建 BigInt (很重要,关键部分)

BigInt(const string& numStr) {
		head = new Node();
		head->data = 0;
		head->next = head;
		head->prev = head;
		isNegative = false;
		
		int startIndex = 0;
		if (numStr[0] == '-') {
			isNegative = true;
			startIndex = 1;
		}
		
		for (int i = numStr.size() - 1; i >= startIndex; i -= 4) {
			int num = 0;
			int multiplier = 1;
			for (int j = 0; j < 4 && i - j >= startIndex; j++) {
				num += (numStr[i - j] - '0') * multiplier;
				multiplier *= 10;
			}
			InsertFront(num);
		}
	}

 从数值构建 Bigint        

BigInt(int num) {
		head = new Node();
		head->data = 0;
		head->next = head;
		head->prev = head;
		isNegative = false;
		
		// 处理整数 num,将其按四位一组插入到 BigInt
		while (num > 0) {
			int fourDigitGroup = num % 10000; // 获取最后四位数
			InsertFront(fourDigitGroup); // 插入四位数
			num /= 10000; // 去除已经处理的四位数
		}
	}
四则远算实现
  实现加法运算
//实现加法运算
	BigInt operator+(const BigInt& other) const {
		
		BigInt result;
	
		// 调用 AddAbsoluteValue 来执行加法操作
		if(isNegative!=other.isNegative) result = SubAbsoluteValue(other);
		else result = AddAbsoluteValue(other);
		
		// 根据操作数的符号来确定结果的符号
		if (isNegative && other.isNegative) {
			// 当前两个数均为负数
			result.setSign(true); // 结果为负数
		}
		else if(compareAbsoluteValue(other)==1&&isNegative){
			//前者是负数,且绝对值大
			result.setSign(true); // 结果为负数
		}
		else if(compareAbsoluteValue(other)==-1&&other.isNegative){
			//后者是负数,且绝对值大
			result.setSign(true); // 结果为负数
		}
		
		return result;
	}
实现减法运算
// 实现减法运算
	BigInt operator-(const BigInt& other) const {
		BigInt result;
		

		// 调用 SubAbsoluteValue 来执行加法操作
		if(other.isNegative!=isNegative)result=AddAbsoluteValue(other);
		else result = SubAbsoluteValue(other);
	
		
		
        // 根据操作数的符号来确定结果的符号
		if (isNegative&&!other.isNegative) {
			// 前负后正
			result.setSign(true); // 结果为负数
		}
		else if(!other.isNegative&&!isNegative&&(compareAbsoluteValue(other)==-1)){
			result.setSign(true); // 都是正数,且前者比后者绝对值小
		}
		else if(compareAbsoluteValue(other)==1&&other.isNegative&&isNegative){
			result.setSign(true); // 都是负数,且后者比前者绝对值小
		}
		return result;
		
		
	}
	
实现乘法运算(手动乘法,从后往前)
  // 实现乘法运算
	BigInt operator*(const BigInt& other) const {
		BigInt result;
     	result=MulAbsoluteValue(other);
       if(isNegative!=other.isNegative){
	        result.setSign(true);
	   } 
	    result.RemoveFrontZeros();
		return result;
	}
实现除法运算(手动除法,从前往后)
   // 实现除法运算
	BigInt operator/(const BigInt& other) const {
		BigInt result;
		result=DivideAbsoluteValue(other);
		if(isNegative!=other.isNegative){
			result.setSign(true);
		} 
		result.RemoveFrontZeros();
		return result;
	}

输出BigInt

// 输出 BigInt
	friend ostream& operator<<(ostream& os,  const BigInt& num) {
		Node* currentNode = num.head->next;
		if (num.isNegative)
			os << "-";
		
		os << currentNode->data;
		currentNode = currentNode->next;
		
		while (currentNode != num.head) {
			os << ",";
			os.width(4);
			os.fill('0');
			os << currentNode->data;
			currentNode = currentNode->next;
		}
		
		return os;
	}
其他必要的函数

    设置 BigInt 对象的正负号

	void setSign(bool negative) {
		isNegative = negative;
	}

比较两个 BigInt 对象的绝对值大小

// 比较两个 BigInt 对象的绝对值大小
	int compareAbsoluteValue(const BigInt& other) const {
		Node* thisNode = head->prev;
		Node* otherNode = other.head->prev;
		int thisSize = 0;
		int otherSize = 0;
		
		// 计算当前对象的绝对值位数
		while (thisNode != head) {
			thisSize++;
			thisNode = thisNode->prev;
		}
		
		// 计算 other 对象的绝对值位数
		while (otherNode != other.head) {
			otherSize++;
			otherNode = otherNode->prev;
		}
		
		// 比较位数
		if (thisSize < otherSize) {
			return -1; // 当前对象的绝对值较小
		} else if (thisSize > otherSize) {
			return 1; // 当前对象的绝对值较大
		}
		
		// 位数相同,逐位比较
		thisNode = head->next;
		otherNode = other.head->next;
		while (thisNode != head) {
			int thisData = thisNode->data;
			int otherData = otherNode->data;
			
			if (thisData < otherData) {
				return -1; // 当前对象的绝对值较小
			} else if (thisData > otherData) {
				return 1; // 当前对象的绝对值较大
			}
			
			thisNode = thisNode->next;
			otherNode = otherNode->next;
		}
		
		// 如果运行到这里,两个对象的绝对值相等
		return 0;
	}

// 绝对值加法函数

// 绝对值加法函数
	BigInt AddAbsoluteValue(const BigInt& other) const {
		BigInt result;
		Node* thisNode = head->prev;
		Node* otherNode = other.head->prev;
		int carry = 0;
		
		while (thisNode != head || otherNode != other.head || carry) {
			int thisData = thisNode != head ? thisNode->data : 0;
			int otherData = otherNode != other.head ? otherNode->data : 0;
			int sum = thisData + otherData + carry;
			carry = sum / 10000;
			result.InsertFront(sum % 10000);
			
			if (thisNode != head)
				thisNode = thisNode->prev;
			if (otherNode != other.head)
				otherNode = otherNode->prev;
		}
		
		return result;
	}
	
	// 绝对值减法函数
	BigInt SubAbsoluteValue(const BigInt& other) const {
		// 如果当前数小于 other,交换操作数,确保大数减小数
        if (compareAbsoluteValue(other) == -1) {
			return other.SubAbsoluteValue(*this);
		}
		
		BigInt result;
		Node* thisNode = head->prev;
		Node* otherNode = other.head->prev;
		int borrow = 0;
		
		while (thisNode != head) {
			int thisData = thisNode->data;
			int otherData = otherNode != other.head ? otherNode->data : 0;
			int diff = thisData - otherData - borrow;
			if (diff < 0) {
				diff += 10000;
				borrow = 1;
			} else {
				borrow = 0;
			}
			result.InsertFront(diff);
			
			if (thisNode != head)
				thisNode = thisNode->prev;
			if (otherNode != other.head)
				otherNode = otherNode->prev;
		}
		
	// 处理当前数多出来的位数
		while (thisNode != head) {
			int thisData = thisNode->data - borrow;
			if (thisData < 0) {
				thisData += 10000;
				borrow = 1;
			} else {
				borrow = 0;
			}
			result.InsertFront(thisData);
			thisNode = thisNode->prev;
		}
		
		result.RemoveFrontZeros();
		return result;
	}

    // 绝对值乘法函数

// 绝对值乘法函数
	BigInt MulAbsoluteValue(const BigInt& other) const {
		BigInt result; // 初始化为0
		int shift = 0;
		
		Node* thisNode = head->prev;
		
		while (thisNode != head) {
			int thisData = thisNode->data;
			int carry = 0;
			Node* otherNode = other.head->prev;
			BigInt tempResult;
			
			// 处理一个四位数与另一个大整数相乘
			while (otherNode != other.head || carry) {
				int otherData = otherNode != other.head ? otherNode->data : 0;
				int product = thisData * otherData + carry;
				carry = product / 10000;
				tempResult.InsertFront(product % 10000);
				
				if (otherNode != other.head)
					otherNode = otherNode->prev;
			}
			
			// 左移结果,相当于乘以 10^4
			for (int i = 0; i < shift; i++) {
				tempResult.InsertBack(0);
			}
			
			result = result.AddAbsoluteValue(tempResult); 
			
			shift++; // 每次处理下一个四位数
			thisNode = thisNode->prev;
		}
		
		return result;
	}

绝对值除法

// 绝对值除法函数
	BigInt DivideAbsoluteValue(const BigInt& divisor) const {
		if (divisor.head->next->data == 0) {
			// 处理除以零的情况
			cout<<"除数不可以为0!不可以计算!"<<endl;
			return 0;
		}
		
		BigInt result; // 初始化为0
		BigInt remainder; // 初始化为0
		BigInt Mul("10000");
		Node* thisNode = head->next; //高位向低位处理
		BigInt partialQuotient;
		while (thisNode != head) {
			remainder = remainder.MulAbsoluteValue(10000).AddAbsoluteValue(thisNode->data);
			
			int quotient = 0;
			
			while (remainder.compareAbsoluteValue( divisor)>=0) {
				remainder = remainder.SubAbsoluteValue(divisor);
				quotient++;
			}
		    
			partialQuotient.InsertBack(quotient);
			thisNode = thisNode->next;
		}	
		result=partialQuotient;
		result.RemoveFrontZeros(); // 处理前导零
		
		return result;
		
	}

main函数

int main() {
	string numStr1, numStr2;
	cout << "请输入第一个长整数: ";
	cin >> numStr1;
	cout << "请输入第二个长整数: ";
	cin >> numStr2;
	
	BigInt num1(numStr1);
	BigInt num2(numStr2);
	BigInt quotient;
	// 执行四则运算
	BigInt sum = num1 + num2;
	BigInt diff = num1 - num2;
	BigInt product = num1 * num2;
    if(!num2.isZero())
    quotient = num1 / num2;
	else cout<<"除法的分母不能为0,除法不作运算!"<<endl;
	
	// 输出结果
	cout << "加法结果: " << sum << endl;
	cout << "减法结果: " << diff << endl;
	cout << "乘法结果: " << product << endl;
	if(!num2.isZero())
	cout << "除法结果(只保留整数部分): " << quotient<< endl;
	system("pause");
	
	return 0;

}

全部代码:

#include <iostream>
#include <string>
using namespace std;

// 定义链表节点结构
struct Node {
	int data;
	Node* next;
	Node* prev;
};

// 定义链表类
class BigInt {
private:
	Node* head; // 头结点
	bool isNegative; // 符号位
	
public:
	BigInt() {
		head = new Node();
		head->data = 0;
		head->next = head;
		head->prev = head;
		isNegative = false;
	}
	//判断是否为0
    int isZero(){
	return (head->next->data==0);
    }
	// 在链表尾部插入数据
	void InsertBack(int data) {
		Node* newNode = new Node();
		newNode->data = data;
		newNode->next = head;
		newNode->prev = head->prev;
		head->prev->next = newNode;
		head->prev = newNode;
	}

	// 移除链表开头多余的零值节点
	void RemoveFrontZeros() {
		Node* currentNode = head->next;
		
		// 移动到第一个非零节点
		while (currentNode != head && currentNode->data == 0) {
			Node* temp = currentNode;
			currentNode = currentNode->next;
			currentNode->prev = head;
			head->next = currentNode;
			delete temp;
		}
	}	
	
	// 插入数据到链表头部
	void InsertFront(int data) {
		Node* newNode = new Node();
		newNode->data = data;
		newNode->next = head->next;
		newNode->prev = head;
		head->next->prev = newNode;
		head->next = newNode;
	}
	
	// 从字符串构建 BigInt
	BigInt(const string& numStr) {
		head = new Node();
		head->data = 0;
		head->next = head;
		head->prev = head;
		isNegative = false;
		
		int startIndex = 0;
		if (numStr[0] == '-') {
			isNegative = true;
			startIndex = 1;
		}
		
		for (int i = numStr.size() - 1; i >= startIndex; i -= 4) {
			int num = 0;
			int multiplier = 1;
			for (int j = 0; j < 4 && i - j >= startIndex; j++) {
				num += (numStr[i - j] - '0') * multiplier;
				multiplier *= 10;
			}
			InsertFront(num);
		}
	}
	
	//从数值构建 Bigint
	BigInt(int num) {
		head = new Node();
		head->data = 0;
		head->next = head;
		head->prev = head;
		isNegative = false;
		
		// 处理整数 num,将其按四位一组插入到 BigInt
		while (num > 0) {
			int fourDigitGroup = num % 10000; // 获取最后四位数
			InsertFront(fourDigitGroup); // 插入四位数
			num /= 10000; // 去除已经处理的四位数
		}
	}

	//实现加法运算
	BigInt operator+(const BigInt& other) const {
		
		BigInt result;
	
		// 调用 AddAbsoluteValue 来执行加法操作
		if(isNegative!=other.isNegative) result = SubAbsoluteValue(other);
		else result = AddAbsoluteValue(other);
		
		// 根据操作数的符号来确定结果的符号
		if (isNegative && other.isNegative) {
			// 当前两个数均为负数
			result.setSign(true); // 结果为负数
		}
		else if(compareAbsoluteValue(other)==1&&isNegative){
			//前者是负数,且绝对值大
			result.setSign(true); // 结果为负数
		}
		else if(compareAbsoluteValue(other)==-1&&other.isNegative){
			//后者是负数,且绝对值大
			result.setSign(true); // 结果为负数
		}
		
		return result;
	}

    // 实现减法运算
	BigInt operator-(const BigInt& other) const {
		BigInt result;
		

		// 调用 SubAbsoluteValue 来执行加法操作
		if(other.isNegative!=isNegative)result=AddAbsoluteValue(other);
		else result = SubAbsoluteValue(other);
	
		
		
        // 根据操作数的符号来确定结果的符号
		if (isNegative&&!other.isNegative) {
			// 前负后正
			result.setSign(true); // 结果为负数
		}
		else if(!other.isNegative&&!isNegative&&(compareAbsoluteValue(other)==-1)){
			result.setSign(true); // 都是正数,且前者比后者绝对值小
		}
		else if(compareAbsoluteValue(other)==1&&other.isNegative&&isNegative){
			result.setSign(true); // 都是负数,且后者比前者绝对值小
		}
		return result;
		
		
	}
	
    // 实现乘法运算
	BigInt operator*(const BigInt& other) const {
		BigInt result;
     	result=MulAbsoluteValue(other);
       if(isNegative!=other.isNegative){
	        result.setSign(true);
	   } 
	    result.RemoveFrontZeros();
		return result;
	}
	
    // 实现除法运算
	BigInt operator/(const BigInt& other) const {
		BigInt result;
		result=DivideAbsoluteValue(other);
		if(isNegative!=other.isNegative){
			result.setSign(true);
		} 
		result.RemoveFrontZeros();
		return result;
	}

    // 输出 BigInt
	friend ostream& operator<<(ostream& os,  const BigInt& num) {
		Node* currentNode = num.head->next;
		if (num.isNegative)
			os << "-";
		
		os << currentNode->data;
		currentNode = currentNode->next;
		
		while (currentNode != num.head) {
			os << ",";
			os.width(4);
			os.fill('0');
			os << currentNode->data;
			currentNode = currentNode->next;
		}
		
		return os;
	}

	// 其他必要的函数
	// 设置 BigInt 对象的正负号
	void setSign(bool negative) {
		isNegative = negative;
	}

	// 比较两个 BigInt 对象的绝对值大小
	int compareAbsoluteValue(const BigInt& other) const {
		Node* thisNode = head->prev;
		Node* otherNode = other.head->prev;
		int thisSize = 0;
		int otherSize = 0;
		
		// 计算当前对象的绝对值位数
		while (thisNode != head) {
			thisSize++;
			thisNode = thisNode->prev;
		}
		
		// 计算 other 对象的绝对值位数
		while (otherNode != other.head) {
			otherSize++;
			otherNode = otherNode->prev;
		}
		
		// 比较位数
		if (thisSize < otherSize) {
			return -1; // 当前对象的绝对值较小
		} else if (thisSize > otherSize) {
			return 1; // 当前对象的绝对值较大
		}
		
		// 位数相同,逐位比较
		thisNode = head->next;
		otherNode = other.head->next;
		while (thisNode != head) {
			int thisData = thisNode->data;
			int otherData = otherNode->data;
			
			if (thisData < otherData) {
				return -1; // 当前对象的绝对值较小
			} else if (thisData > otherData) {
				return 1; // 当前对象的绝对值较大
			}
			
			thisNode = thisNode->next;
			otherNode = otherNode->next;
		}
		
		// 如果运行到这里,两个对象的绝对值相等
		return 0;
	}
	
	// 绝对值加法函数
	BigInt AddAbsoluteValue(const BigInt& other) const {
		BigInt result;
		Node* thisNode = head->prev;
		Node* otherNode = other.head->prev;
		int carry = 0;
		
		while (thisNode != head || otherNode != other.head || carry) {
			int thisData = thisNode != head ? thisNode->data : 0;
			int otherData = otherNode != other.head ? otherNode->data : 0;
			int sum = thisData + otherData + carry;
			carry = sum / 10000;
			result.InsertFront(sum % 10000);
			
			if (thisNode != head)
				thisNode = thisNode->prev;
			if (otherNode != other.head)
				otherNode = otherNode->prev;
		}
		
		return result;
	}
	
	// 绝对值减法函数
	BigInt SubAbsoluteValue(const BigInt& other) const {
		// 如果当前数小于 other,交换操作数,确保大数减小数
        if (compareAbsoluteValue(other) == -1) {
			return other.SubAbsoluteValue(*this);
		}
		
		BigInt result;
		Node* thisNode = head->prev;
		Node* otherNode = other.head->prev;
		int borrow = 0;
		
		while (thisNode != head) {
			int thisData = thisNode->data;
			int otherData = otherNode != other.head ? otherNode->data : 0;
			int diff = thisData - otherData - borrow;
			if (diff < 0) {
				diff += 10000;
				borrow = 1;
			} else {
				borrow = 0;
			}
			result.InsertFront(diff);
			
			if (thisNode != head)
				thisNode = thisNode->prev;
			if (otherNode != other.head)
				otherNode = otherNode->prev;
		}
		
	// 处理当前数多出来的位数
		while (thisNode != head) {
			int thisData = thisNode->data - borrow;
			if (thisData < 0) {
				thisData += 10000;
				borrow = 1;
			} else {
				borrow = 0;
			}
			result.InsertFront(thisData);
			thisNode = thisNode->prev;
		}
		
		result.RemoveFrontZeros();
		return result;
	}
	
	// 绝对值乘法函数
	BigInt MulAbsoluteValue(const BigInt& other) const {
		BigInt result; // 初始化为0
		int shift = 0;
		
		Node* thisNode = head->prev;
		
		while (thisNode != head) {
			int thisData = thisNode->data;
			int carry = 0;
			Node* otherNode = other.head->prev;
			BigInt tempResult;
			
			// 处理一个四位数与另一个大整数相乘
			while (otherNode != other.head || carry) {
				int otherData = otherNode != other.head ? otherNode->data : 0;
				int product = thisData * otherData + carry;
				carry = product / 10000;
				tempResult.InsertFront(product % 10000);
				
				if (otherNode != other.head)
					otherNode = otherNode->prev;
			}
			
			// 左移结果,相当于乘以 10^4
			for (int i = 0; i < shift; i++) {
				tempResult.InsertBack(0);
			}
			
			result = result.AddAbsoluteValue(tempResult); 
			
			shift++; // 每次处理下一个四位数
			thisNode = thisNode->prev;
		}
		
		return result;
	}
	
    // 绝对值除法函数
	BigInt DivideAbsoluteValue(const BigInt& divisor) const {
		if (divisor.head->next->data == 0) {
			// 处理除以零的情况
			cout<<"除数不可以为0!不可以计算!"<<endl;
			return 0;
		}
		
		BigInt result; // 初始化为0
		BigInt remainder; // 初始化为0
		BigInt Mul("10000");
		Node* thisNode = head->next; //高位向低位处理
		BigInt partialQuotient;
		while (thisNode != head) {
			remainder = remainder.MulAbsoluteValue(10000).AddAbsoluteValue(thisNode->data);
			
			int quotient = 0;
			
			while (remainder.compareAbsoluteValue( divisor)>=0) {
				remainder = remainder.SubAbsoluteValue(divisor);
				quotient++;
			}
		    
			partialQuotient.InsertBack(quotient);
			thisNode = thisNode->next;
		}	
		result=partialQuotient;
		result.RemoveFrontZeros(); // 处理前导零
		
		return result;
		
	}

};

int main() {
	string numStr1, numStr2;
	cout << "请输入第一个长整数: ";
	cin >> numStr1;
	cout << "请输入第二个长整数: ";
	cin >> numStr2;
	
	BigInt num1(numStr1);
	BigInt num2(numStr2);
	BigInt quotient;
	// 执行四则运算
	BigInt sum = num1 + num2;
	BigInt diff = num1 - num2;
	BigInt product = num1 * num2;
    if(!num2.isZero())
    quotient = num1 / num2;
	else cout<<"除法的分母不能为0,除法不作运算!"<<endl;
	
	// 输出结果
	cout << "加法结果: " << sum << endl;
	cout << "减法结果: " << diff << endl;
	cout << "乘法结果: " << product << endl;
	if(!num2.isZero())
	cout << "除法结果(只保留整数部分): " << quotient<< endl;
	system("pause");
	
	return 0;

}

测试界面:

  1. num1>0,num2>0,|num1|>=|num2|
  1. num1>0,num2>0,|num1|<|num2
  1. num1<0,num2>0,|num1|>=|num2|
  1. num1<0,num2>0,|num1|<|num2|
  1. num1>0,num2<0,|num1|>=|num2|
  1. num1>0,num2<0,|num1|<|num2|
  1. num1<0,num2<0,|num1|>=|num2|
  1. num1<0,num2<0,|num1|<|num2|
  1. num1=0
  1. Num2=0

以上测试结果均符合预期结果。

  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值