要求:
任意长整数的输入输出格式为每 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;
}
测试界面:
- num1>0,num2>0,|num1|>=|num2|
- num1>0,num2>0,|num1|<|num2
- num1<0,num2>0,|num1|>=|num2|
- num1<0,num2>0,|num1|<|num2|
- num1>0,num2<0,|num1|>=|num2|
- num1>0,num2<0,|num1|<|num2|
- num1<0,num2<0,|num1|>=|num2|
- num1<0,num2<0,|num1|<|num2|
- num1=0
- Num2=0
以上测试结果均符合预期结果。