当前位置: 首页 > news >正文

北邮22信通:(8)实验1 题目五:大整数加减法(搬运官方代码)

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

上一篇文章:

北邮22信通:(7)实验1 题目四:一元多项式(节省内存版)_青山如墨雨如画的博客-CSDN博客

下一篇文章:

*****声明*****

本代码由官方提供,不是作者的算法。

本代码仅供研究学习使用,请不要用于其他用途。

有问题的友友也可以在评论区留言,我们可以一起讨论。

本代码在DEVC++中可以运行。

*****声明完毕*****

1.实验要求:

利用链表实现大整数加减法操作;32位极其直接操作的数据最大为32bit,若超过32bit,则需要单独设计算法。在这里,可以用链表的每个节点存储大整数的每一位的十进制数字,则可以进行大整数的算术运算,该实验仅实现加减法操作。

要求:

随机产生2个1~50位的字符串,并存储到新的链表中;

打印运算结果。

考虑链表结构的设计,是否有更节省空间的数据结构。

2.代码部分:

#include <iosfwd>
#include <iostream>
#include <stack>
#include "time.h"
using namespace std;struct Node
{int data;Node  *next;
};
class BigInteger
{
public:BigInteger();BigInteger(int a[], int n, bool pos);friend BigInteger add(BigInteger &int1, BigInteger &int2);  //int1 + int2friend BigInteger sub(BigInteger &int1, BigInteger &int2);  //int1 - int2int getLength();                   //获取链表长度void print();~BigInteger();
private:Node *first;int length;bool positive = true;   //记录整数的正负
};BigInteger::BigInteger()
{first = new Node;first->data = 0;first->next = NULL;length = 1;
}BigInteger::BigInteger(int a[], int n, bool pos = true)	//引用和声明只能有一个默认参数定义
{if (n < 1){throw "integer length should be at least 1";}//尾插法 不带头结点的链表first = new  Node;Node *r = first;  //指向最后一个结点for (int i = 0; i<n - 1; i++){r->data = a[i];Node *s = new Node; //(1)生成新结点s->next = NULL;r->next = s;  //(2) 链接在尾结点后面r = s; //(3) 尾指针后移}r->data = a[n-1];r->next = NULL;length = n;positive = pos;
}
BigInteger::~BigInteger() {}BigInteger sub(BigInteger &int1, BigInteger &int2) {      //都可以转换成正数的加减法BigInteger newint = BigInteger();newint.length = 0;              //友元能直接访问私有变量if ((!int1.positive)&&(!int2.positive)){    //-int1-(-int2) = -int1 + int2int2.positive = true;newint = add(int1,int2);int2.positive = false;return newint;}else if (!int1.positive){int1.positive = true;newint = add(int1,int2);newint.positive = false;int1.positive = false;return newint;}else if (!int2.positive){int2.positive = true;newint = add(int1,int2);int2.positive = false;return newint;}// 这里开始的处理,int1和int2应都为正整数Node *cursor = new Node;    //游标用来创建新的链表Node *tobedelete = cursor;      //临时的头结点cursor->next = newint.first;    Node *int1_first = int1.first;     //遍历int1Node *int2_first = int2.first;     //遍历int2stack<Node*> substk;  //定义一个栈用来处理高位的连续0  如77772-77771 = 1 ,需要把前面的0都删除int flag = 0;   //记录减法的借位//首先遍历到 min(int1.length, int2.length)位,之后至少有一个指针为NULLfor (int i = 0; i < int1.length && i < int2.length; i++){int tmp = int1_first->data - int2_first->data - flag;if (tmp < 0){tmp += 10;if (tmp == 0){substk.push(cursor);    //1000 - 99 = 901}else{while (!substk.empty())      //有出现不为0的位,就把栈清空substk.pop();}flag = 1;}else if ((tmp == 0)&&(cursor->next!=newint.first)){  //个位为0不入栈,入栈的是0前面的结点substk.push(cursor);flag = 0;}else{while (!substk.empty())substk.pop();flag = 0;}cursor->next->data = tmp;       //在结果链表中插入新节点cursor->next->next = new Node;cursor = cursor->next;cursor->next->next = NULL;int1_first = int1_first->next;int2_first = int2_first->next;newint.length++;}//减完位数相同的部分,讨论接下来的情况if ((int1_first == NULL) && (int2_first == NULL)){if (!flag == 0)        //最高位有借位说明结果是负的,在后面计算补码newint.positive = false;}else if(int1_first == NULL){// int2位数多,结果一定是负数newint.positive = false;while (int2_first != NULL){int tmp = 0 - int2_first->data - flag;if (tmp < 0){tmp += 10;if (tmp == 0){substk.push(cursor);}else{while (!substk.empty())substk.pop();}flag = 1;}else if (tmp == 0){substk.push(cursor);flag = 0;}else{while (!substk.empty())substk.pop();flag = 0;}cursor->next->data = tmp;cursor->next->next = new Node;cursor = cursor->next;cursor->next->next = NULL;newint.length++;int2_first = int2_first->next;}}else{while (int1_first != NULL){// int1位数高,结果必为正int tmp = int1_first->data - flag;if (tmp < 0){tmp += 10;if (tmp == 0){substk.push(cursor);}else{while (!substk.empty())substk.pop();}flag = 1;}else if (tmp == 0){substk.push(cursor);flag = 0;}else{while (!substk.empty())substk.pop();flag = 0;}cursor->next->data = tmp;cursor->next->next = new Node;cursor = cursor->next;cursor->next->next =NULL;newint.length++;int1_first = int1_first->next;}}//删除初始化的临时节点delete tobedelete;//删除末尾的临时节点tobedelete = cursor->next;cursor->next = NULL;delete tobedelete;//删除最后的连续0节点while (!substk.empty()){cursor = substk.top();if (cursor->next == newint.first)  //个位不能被删除(删除的也不是个位,tobedelete已经被释放了)break;substk.pop();tobedelete = cursor->next;cursor->next = NULL;newint.length--;delete tobedelete;}if (!newint.positive){//得到的newint为负数,需要补码操作,如9-16 -> 93,100-93 = 7int a[int2.length+1];for (int i = 0; i < int2.length;i++)a[i] = 0;a[int2.length] = 1;newint.positive = true;BigInteger complement = BigInteger(a,newint.length + 1);tobedelete = newint.first;newint = sub(complement,newint);    //newint的地址换了,构造了一个新对象newint.positive = false;while (tobedelete != NULL){Node *tobed = tobedelete;tobedelete = tobedelete->next;delete tobed;}}return newint;
}BigInteger add(BigInteger &int1, BigInteger &int2) {BigInteger newint = BigInteger();  //定义新的大整数作为返回值newint.length = 0;if ((!int1.positive)&&(!int2.positive))newint.positive = false;else if(!int1.positive){int1.positive = true;newint = sub(int2,int1);int1.positive = false;return newint;}else if(!int2.positive){int2.positive = true;newint = sub(int1,int2);int2.positive = false;return newint;}// 这里开始的处理,int1和int2应都为正整数Node *cursor = new Node;    //创建一个游标指针用于构建newintNode *tobedelete = cursor;  //记录临时用的节点位置,最后删掉,防止内存泄漏cursor->next = newint.first;Node *int1_first = int1.first;Node *int2_first = int2.first;int flag = 0;  //记录加法的进位//首先遍历到 min(int1.length, int2.length)位,之后至少有一个指针为NULLfor (int i = 0; i < int1.length && i < int2.length; i++){int tmp = int1_first->data + int2_first->data + flag;if (tmp >= 10){tmp -= 10;flag = 1;} elseflag = 0;cursor->next->data = tmp;cursor->next->next = new Node;cursor = cursor->next;int1_first = int1_first->next;int2_first = int2_first->next;newint.length++;}if ((int1_first == NULL) && (int2_first == NULL)){}else if(int1_first == NULL){// int2的位数多while (int2_first != NULL){int tmp = int2_first->data + flag;if (tmp >= 10){tmp -= 10;flag = 1;} elseflag = 0;cursor->next->data = tmp;cursor->next->next = new Node;cursor = cursor->next;newint.length++;int2_first = int2_first->next;}}else{while (int1_first != NULL){// int1的位数多int tmp = int1_first->data + flag;if (tmp >= 10){tmp -= 10;flag = 1;} elseflag = 0;cursor->next->data = tmp;cursor->next->next = new Node;cursor = cursor->next;newint.length++;int1_first = int1_first->next;}}delete tobedelete; //删除初始化的临时节点,防止内存泄漏if (flag != 1){//如果最后没有进位,删除末尾的临时节点,防止内存泄漏tobedelete = cursor->next;cursor->next = NULL;delete tobedelete;return newint;}else{//如果有进位,则将数据赋到末尾节点cursor->next->data = 1;cursor->next->next = NULL;newint.length++;}return newint;
}int BigInteger::getLength() //O(1)
{return this->length;
}void BigInteger::print() {stack<int> s;Node *p = first;while (p != NULL){s.push(p->data);p = p->next;}if(!positive)cout << "-";while (!s.empty()){int tmp = s.top();cout << tmp;s.pop();}
}int main()
{//从低位到高位//{个,十,百,千,万,...}int nums1[2] = {2,3};BigInteger int1(nums1, 2);int nums2[2] = {2,3};BigInteger int2(nums2, 2);// srand((unsigned )time(NULL));    //随机数种子// int n = rand() % 50 +1;// int nums1[n];// for(int i = 0; i < n; i++)// {//     nums1[i] = rand()%10;// }// if(nums1[n-1] == 0)//     nums1[n-1] = 1;// BigInteger int1(nums1,n);// n = rand() % 50 + 1;// int nums2[n];// for(int i = 0; i < n; i++)// {//     nums2[i] = rand()%10;// }// if(nums2[n-1] == 0)//     nums2[n-1] = 1;// BigInteger int2(nums2, n);cout << "int1: ";int1.print();cout << endl;cout << "int2: ";int2.print();cout << endl;try{cout << "*********************" << endl;BigInteger newint = add(int1,int2);newint.print();cout << "=";int1.print();cout << "+";int2.print();cout << endl;cout << "*********************" << endl;BigInteger subint = sub(int1,int2);subint.print();cout << "=";int1.print();cout << "-";int2.print();cout << endl;}catch (const char* e){cout << e << endl;return 0;}return 0;
}

程序运行结果:

相关文章:

北邮22信通:(8)实验1 题目五:大整数加减法(搬运官方代码)

北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 上一篇文章&#xff1a; 北邮22信通&#xff1a;&#xff08;7&#xff09;实验1 题目四&#xff1a;一元多项式&#xff08;节省内存版&#xff09;_青山如…...

Fiddler抓取https史上最强教程

有任何疑问建议观看下面视频 2023最新Fiddler抓包工具实战&#xff0c;2小时精通十年技术&#xff01;&#xff01;&#xff01;对于想抓取HTTPS的测试初学者来说&#xff0c;常用的工具就是fiddler。 但是初学时&#xff0c;大家对于fiddler如何抓取HTTPS难免走歪路&#xff…...

STM32开发基础知识入门

C语言基础 位操作 对基本类型变量可以在位级别进行操作。 1) 不改变其他位的值的状况下&#xff0c;对某几个位进行设值。 先对需要设置的位用&操作符进行清零操作&#xff0c;然后用|操作符设值。 2) 移位操作提高代码的可读性。 3) ~取反操作使用技巧 可用于对某…...

学习操作系统的必备教科书《操作系统:原理与实现》| 文末赠书4本

使用了6年的实时操作系统&#xff0c;是时候梳理一下它的知识点了 摘要&#xff1a; 本文简单介绍了博主学习操作系统的心路历程&#xff0c;同时还给大家总结了一下当下流行的几种实时操作系统&#xff0c;以及在工程中OSAL应该如何设计。希望对大家有所启发和帮助。 文章目录…...

大数据的常用算法(分类、回归分析、聚类、关联规则、神经网络方法、web数据挖掘)

在大数据时代&#xff0c;数据挖掘是最关键的工作。大数据的挖掘是从海量、不完全的、有噪声的、模糊的、随机的大型数据库中发现隐含在其中有价值的、潜在有用的信息和知识的过程&#xff0c;也是一种决策支持过程。其主要基于人工智能&#xff0c;机器学习&#xff0c;模式学…...

【数据结构】详解二叉树与堆与堆排序的关系

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 &#x1f6f8;C语言专栏&#xff1a;https://blog.csdn.net/vhhhbb/category_12174730.html &#x1f680;数据结构专栏&#xff…...

【Pandas】数据分析入门

文章目录前言一、Pandas简介1.1 什么是Pandas1.2 Pandas应用二、Series结构2.1 Series简介2.2 基本使用三、DataFrame结构3.1 DataFrame简介3.2 基本使用四、Pandas-CSV4.1 CSV简介4.2 读取CSV文件4.3 数据处理五、数据清洗5.1 数据清洗的方法5.2 清洗案例总结前言 大家好&…...

【c++】:list模拟实现“任意位置插入删除我最强ƪ(˘⌣˘)ʃ“

文章目录 前言一.list的基本功能的使用二.list的模拟实现总结前言 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。2. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0…...

QT表格控件实例(Table Widget 、Table View)

欢迎小伙伴的点评✨✨&#xff0c;相互学习&#x1f680;&#x1f680;&#x1f680; 博主&#x1f9d1;&#x1f9d1; 本着开源的精神交流Qt开发的经验、将持续更新续章&#xff0c;为社区贡献博主自身的开源精神&#x1f469;‍&#x1f680; 文章目录前言一、图示实例二、列…...

第二章Vue组件化编程

文章目录模块与组件、模块化与组件化模块组件模块化组件化Vue中的组件含义非单文件组件基本使用组件注意事项使用 kebab-case使用 PascalCase组件的嵌套模板templateVueComponent一个重要的内置功能单文件组件Vue脚手架使用Vue CLI脚手架先配置环境初始化脚手架分析脚手架结构实…...

面试官:vue2和vue3的区别有哪些

目录 多根节点&#xff0c;fragment&#xff08;碎片&#xff09; Composition API reactive 函数是用来创建响应式对象 Ref toRef toRefs 去除了管道 v-model的prop 和 event 默认名称会更改 vue2写法 Vue 3写法 vue3组件需要使用v-model时的写法 其他语法 1. 创…...

【TopK问题】——用堆实现

文章目录一、TopK问题是什么二、解决方法三、时间复杂度一、TopK问题是什么 TopK问题就是从1000个数中找出前K个最大的数或者最小的数这样的类似问题。 不过并不要求这k个数字必须是有序的&#xff0c;如果题目有要求&#xff0c;则进行堆排序即可。 还有比如求出全国玩韩信…...

【Spring从成神到升仙系列 四】从源码分析 Spring 事务的来龙去脉

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到升仙…...

使用Nginx反向代理OpenAI API

由于OpenAI的API在国内无法访问&#xff0c;所以可以通过海外服务器利用Nginx实现反向代理。 安装Nginx 这一步就不赘述了&#xff0c;不同的Linux系统安装方式略有不同&#xff0c;根据自己的服务器的系统自行百度即可。 OpenSSL创建证书 因为OpenAI的接口是https协议的&a…...

USB键盘实现——字符串描述符(四)

字符串描述符 字符串描述符内容解析和 HID鼠标 一致。 获取字符串描述符请求 标准设备请求 typedef struct __attribute__ ((packed)){union {struct __attribute__ ((packed)) {uint8_t recipient : 5; ///< Recipient type usb_request_recipient_t.uint8_t type …...

STM32的中断

目录 一、STM32中断概述 二、外部中断控制器EXTI 三、按键中断 四、串口中断 一、STM32中断概述 处理器中的中断在处理器中&#xff0c;中断是一个过程&#xff0c;即CPU在正常执行程序的过程中&#xff0c;遇到外部/内部的紧急事件需要处理&#xff0c;暂时中止当前程序的…...

Flink进阶篇-CDC 原理、实践和优化采集到Doris中

简介 基于doris官方用doris构建实时仓库的思路&#xff0c;从flinkcdc到doris实时数仓的实践。 原文 Apache Flink X Apache Doris 构建极速易用的实时数仓架构 (qq.com) 前提-Flink CDC 原理、实践和优化 CDC 是什么 CDC 是变更数据捕获&#xff08;Change Data Captur…...

看完这篇 教你玩转渗透测试靶机vulnhub——My File Server: 1

Vulnhub靶机My File Server: 1渗透测试详解Vulnhub靶机介绍&#xff1a;Vulnhub靶机下载&#xff1a;Vulnhub靶机安装&#xff1a;Vulnhub靶机漏洞详解&#xff1a;①&#xff1a;信息收集&#xff1a;②&#xff1a;FTP匿名登入&#xff1a;③&#xff1a;SMB共享服务&#xf…...

OpenHarmony实战STM32MP157开发板 “控制” Hi3861开发板 -- 中篇

一、前言 我们在 OpenHarmony实战STM32MP157开发板 “控制” Hi3861开发板 – 上篇 中介绍到了,App面板的开发,以及JS API接口的开发和调用。 那么本篇文章,会详解:BearPi-HM Nano开发板,如何实现数据上报和指令接收响应的。 看到这里,可能有同学可能已经知道思路了,因…...

【数据结构初阶】单链表

目录一、思路>>>>>>>>>>>>过程<<<<<<<<<<<<<<<1.打印2.尾插3.尾删4.头插5.头删6.查找7.指定位置后插入8.指定位置后删除9.链表的销毁二、整个程序1.SLTlist.c2.SLTlist.c一、思路 #define …...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...