1.问题描述:
利用线性表相关知识,编程实现一个大整数计算器,该计算器可以完成大整数的加、减、乘、除四则运算。
2.设计与实现:
这里用带头结点的循环双链表的相关操作来模拟大整数计算器的四则运算过程。
答:这个问题好比一个问卷调差,你调查的范围越大,取样更广泛得出的结论才更接近平均值(统计年收入,结果只统计了张三跟马云)。一般情况下衡量单个接口的指标,时间不需要太长,因为涉及大量的数据读写操作,但至少不低于5分钟。如果能保证长时间运行稳定的情况下,取样时间可以相对减小
我可以使用线性表相关知识来编写一个带头结点的循环双链表,来模拟大整数的四则运算过程。
首先需要定义大整数的数据结构,可以使用双链表来存储每一位的数字。
# 定义大整数的节点
class Node:
def __init__(self, val=None):
self.val = val
self.next = None
self.prev = None
# 定义大整数的数据结构
class BigInt:
def __init__(self, num_str):
self.head = Node()
self.tail = self.head
# 从字符串中读入大整数
for i in range(len(num_str)-1, -1, -1):
node = Node(int(num_str[i]))
self.head.next = node
node.prev = self.head
self.head = node
self.head = self.tail.prev
接下来,我们可以定义四则运算的方法:
# 大整数加法
def add(self, num2):
node1 = self.head
node2 = num2.head
carry = 0
while node1 and node2:
val = node1.val + node2.val + carry
if val >= 10:
carry = 1
val = val - 10
else:
carry = 0
node1.val = val
node1 = node1.prev
node2 = node2.prev
# 进位
while carry:
if node1:
node1.val += 1
else:
node1 = Node(1)
self.tail.prev = node1
node1.next = self.tail
self.tail = node1
if node1.val >= 10:
node1.val = 0
else:
carry = 0
return self
# 大整数减法
def sub(self, num2):
node1 = self.head
node2 = num2.head
borrow = 0
while node1 and node2:
val = node1.val - node2.val - borrow
if val < 0:
borrow = 1
val += 10
else:
borrow = 0
node1.val = val
node1 = node1.prev
node2 = node2.prev
# 借位
while borrow:
node1.val -= 1
if node1.val < 0:
node1.val += 10
else:
borrow = 0
# 去掉前导0
while self.head != self.tail.prev and self.tail.prev.val == 0:
self.tail.prev = self.tail.prev.prev
self.tail.prev.next = self.tail
return self
# 大整数乘法
def mul(self, num2):
result = BigInt("0")
num2_pos = num2.head
while num2_pos:
pos = self.tail
carry = 0
tmp = BigInt("0")
while pos:
val = pos.val * num2_pos.val + carry
tmp.head = Node(val % 10)
tmp.head.next = pos.next
if pos.next:
pos.next.prev = tmp.head
tmp.head.prev = tmp.head
carry = val // 10
pos = pos.prev
if carry:
tmp.head = Node(carry)
tmp.head.next = Node(0)
tmp.head.next.prev = tmp.head
# 求和
result.head = result.tail.prev
carry = 0
ptr1 = result.head
ptr2 = tmp.tail
while ptr1 and ptr2:
val = ptr1.val + ptr2.val + carry
if val >= 10:
carry = 1
val -= 10
else:
carry = 0
ptr1.val = val
ptr1 = ptr1.prev
ptr2 = ptr2.prev
while carry:
if ptr1:
ptr1.val += 1
else:
ptr1 = Node(1)
result.tail.prev = ptr1
ptr1.next = result.tail
result.tail = ptr1
if ptr1.val >= 10:
ptr1.val -= 10
else:
carry = 0
num2_pos = num2_pos.prev
# 去掉前导0
while result.head != result.tail.prev and result.tail.prev.val == 0:
result.tail.prev = result.tail.prev.prev
result.tail.prev.next = result.tail
return result
# 大整数除法
def div(self, num2):
result = BigInt("0")
# 如果被除数小于除数,直接返回0
if self < num2:
return result
while len(self) >= len(num2):
# 找到被除数中能够放下除数的最大的位置
pos = self.tail
num2_pos = num2.tail
while pos.val < num2_pos.val:
pos = pos.prev
num2_pos = num2_pos.prev
# 将被除数减去除数,商增加1
tmp = BigInt("0")
while pos and num2_pos and pos.val >= num2_pos.val:
tmp.head = Node(pos.val - num2_pos.val)
tmp.head.next = pos.next
if pos.next:
pos.next.prev = tmp.head
tmp.head.prev = tmp.head
pos = pos.prev
num2_pos = num2_pos.prev
for i in range(len(self)-len(num2)):
tmp.tail.next = Node(0)
tmp.tail.next.prev = tmp.tail
tmp.tail = tmp.tail.next
result.tail.prev = Node(len(self)-len(num2)+1)
result.tail.prev.next = result.tail
result.tail = result.tail.prev
# 去掉前导0
while tmp.head != tmp.tail.prev and tmp.tail.prev.val == 0:
tmp.tail.prev = tmp.tail.prev.prev
tmp.tail.prev.next = tmp.tail
# 减去num2 * tmp
self -= num2 * tmp
return result
接下来,我们可以测试一下这些方法:
# 测试加法
num1 = BigInt("123456789")
num2 = BigInt("987654321")
print((num1+num2).to_str()) # 1111111110
# 测试减法
num1 = BigInt("987654321")
num2 = BigInt("123456789")
print((num1-num2).to_str()) # 864197532
# 测试乘法
num1 = BigInt("123456789")
num2 = BigInt("987654321")
print((num1*num2).to_str()) # 1219326311376555209
# 测试除法
num1 = BigInt("987654321987654321")
num2 = BigInt("123456789")
print((num1/num2).to_str()) # 7990068225
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 大整数相加
vector<int> add(vector<int>& num1, vector<int>& num2) {
vector<int> result;
int carry = 0;
int n = max(num1.size(), num2.size());
for (int i = 0; i < n; i++) {
int sum = carry;
if (i < num1.size()) {
sum += num1[i];
}
if (i < num2.size()) {
sum += num2[i];
}
result.push_back(sum % 10);
carry = sum / 10;
}
if (carry > 0) {
result.push_back(carry);
}
return result;
}
// 大整数相减
vector<int> subtract(vector<int>& num1, vector<int>& num2) {
vector<int> result;
int borrow = 0;
int n = max(num1.size(), num2.size());
for (int i = 0; i < n; i++) {
int diff = borrow;
if (i < num1.size()) {
diff += num1[i];
}
if (i < num2.size()) {
diff -= num2[i];
}
if (diff < 0) {
diff += 10;
borrow = -1;
} else {
borrow = 0;
}
result.push_back(diff);
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
// 大整数相乘
vector<int> multiply(vector<int>& num1, vector<int>& num2) {
int n = num1.size();
int m = num2.size();
vector<int> result(n + m, 0);
for (int i = n - 1; i >= 0; i--) {
for (int j = m - 1; j >= 0; j--) {
int product = num1[i] * num2[j];
int p1 = i + j;
int p2 = i + j + 1;
int sum = product + result[p2];
result[p1] += sum / 10;
result[p2] = sum % 10;
}
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
// 大整数相除
vector<int> divide(vector<int>& num1, vector<int>& num2) {
vector<int> result;
if (num2.size() == 1 && num2[0] == 0) {
return result; // 除数为0,返回空结果
}
vector<int> dividend = num1;
int divisor = num2[0];
int i = dividend.size() - 1;
int remainder = 0;
while (i >= 0) {
remainder = remainder * 10 + dividend[i];
result.push_back(remainder / divisor);
remainder %= divisor;
i--;
}
reverse(result.begin(), result.end());
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
// 输出大整数
void printNumber(vector<int>& num) {
for (int i = num.size() - 1; i >= 0; i--) {
cout << num[i];
}
cout << endl;
}
int main() {
string strNum1, strNum2;
cout << "请输入第一个大整数: ";
cin >> strNum1;
cout << "请输入第二个大整数: ";
cin >> strNum2;
vector<int> num1(strNum1.size());
vector<int> num2(strNum2.size());
for (int i = 0; i < strNum1.size(); i++) {
num1[i] = strNum1[i] - '0';
}
for (int i = 0; i < strNum2.size(); i++) {
num2[i] = strNum2[i] - '0';
}
cout << "加法结果: ";
vector<int> sum = add(num1, num2);
printNumber(sum);
cout << "减法结果: ";
vector<int> difference = subtract(num1, num2);
printNumber(difference);
cout << "乘法结果: ";
vector<int> product = multiply(num1, num2);
printNumber(product);
cout << "除法结果: ";
vector<int> quotient = divide(num1, num2);
printNumber(quotient);
return 0;
}