当前位置:网站首页>dhu编程练习
dhu编程练习
2022-06-30 02:08:00 【qq_43403657】
9 长整数加法运算
1.问题描述
假设2个任意长度的整数x、y分别由双向链表A和B存储,现要求设计一个算法,实现x+y。计算结果存储在链表C中。
说明:
由于A和B输出时需要从头至尾遍历,而做加法时需要从尾至头遍历,因此使用双向链表存储。
可以从长整数的低位开始拆分(4位为一组,即不超过9999的非负整数),依次存放在链表的每个结点的数据域中;头结点的数据域存放正负数标志(正数或0:1,负数:-1)。
2.输入说明
第一行:长整数x
第二行:长整数y
3.输出说明
第一行:格式化后的长整数x(从低位到高位每4位用","分开)
第二行:格式化后的长整数y(从低位到高位每4位用","分开)
第三行:空行
第四行:单链表C的遍历结果
第五行:格式化后的计算结果(从低位到高位每4位用","分开)
(输入与输出之间用一空行分隔)
4.范例
输入
-53456467576846547658679870988098
435643754856985679
输出
-5345,6467,5768,4654,7658,6798,7098,8098
43,5643,7548,5698,5679
5345->6467->5768->4611->2014->9250->1400->2419
-5345,6467,5768,4611,2014,9250,1400,2419
5.代码
#include <iostream>
#include <string> //cin>>s1>>s2;
#include <math.h>
#include<algorithm> //使用reverse()函数
using namespace std;
//头结点的数据域存放正负数标志(正数或0:1,负数:-1) head->num=1(0或者正数)
struct node {
int num;
struct node* pre;
struct node* next;
};
struct node* create(string s) {
//由于链表从尾部到头部相加,所以结果采用头插法插入
//1.新建头结点并初始化
struct node* head = new node;
head->next = NULL;
head->pre = NULL;
//2.计算链表真正长度
int len=s.length();
if (s[len - 1] == '-') {
len = s.length() - 1;
head->num = -1;
}
else {
len = s.length();
head->num = 1;
}
//3.进行相加工作,num保存结果数值,cnt用于控制每四位相加
int cnt = 0;
int num = 0;
for (int i = 0; i < len; i++) {
//num += (int)(s[i] - '0') * (pow(10, cnt) + 0.1);//此处改成num +=(s[i] - '0') * pow(10, cnt);
num += (s[i] - '0') * pow(10, cnt);
cnt++;
if (cnt == 4 || i == len - 1) {
//当读取4个数时重置
struct node* p = new node;
struct node* q = head->next;
p->num = num;//p所指为新建结点
head->next = p;
p->pre = head;
p->next = q;
//链表中除了头结点,还有其他结点
if (q)
q->pre = p;
cnt = 0;
num = 0;
}
}
return head;
}
void display(struct node* head) {
if (head->next) {
//存在数据时
if (head->num == -1)
cout << '-';
struct node* p = head->next;
cout << p->num;
p = p->next;
while (p) {
printf(",%04d", p->num);
p = p->next;
}
}
else
cout << 0; //注意这里要考虑到没有数据的情况
}
struct node* add(struct node* num1, struct node* num2) {
//两个链表相加情况 ,类似于合并链表操作
struct node* head = new node;
head->next = NULL;
head->pre = NULL;
struct node* p = num1;
struct node* q = num2;
while (p->next)
p = p->next;
while (q->next)
q = q->next;
//1.链表num1,num2均非空
while (p != num1 && q != num2) {
//从尾部到头部进行遍历
struct node* t = new node;
struct node* f = head->next;
t->num = num1->num*p->num + num2->num*q->num; //num1->num代表链表L1的符号 , num2->num代表链表L2的符号
//t->num = p->num + q->num;这应该不行,因为Line :155处开始有关于符号的处理
head->next = t;
t->pre = head;
t->next = f;
if (f)
f->pre = t;
p = p->pre;
q = q->pre;
}
//2.链表num1非空,num2已空
while (p != num1) {
//类似于合并有序表,对没有运算的结点采用头部插入的方法
struct node* t = new node;
struct node* h = head->next;
t->num = num1->num * p->num;
head->next = t;
t->pre = head;
t->next = h;
if (h)
h->pre = t;
p = p->pre;
}
//3.链表num2非空,num1已空
while (q != num2) {
struct node* t = new node;
struct node* o = head->next;
t->num = num2->num * q->num;
head->next = t;
t->pre = head;
t->next = o;
if (o)
o->pre = t;
q = q->pre;
}
//4.判断最后的取值是正是负
if (head->next->num > 0)
head->num = 1;
else
head->num = -1;
p = head;
while (p->next)
p = p->next;
q = p;//q指向链表尾部结点
/*接下来部分理解很重要!!!*/
//5.处理进位情况 p指向链表尾部,逐步向前遍历
while (p != head) {
//p指向链表尾部结点
//关键:处理有进位的情况
if (p->num * head->num < 0) {
//正数借位减一,负数借位加1
if (head->num > 0) {
//正数
p->num += 10000;
p->pre->num -= 1;
}
else {
p->num -= 10000;
p->pre->num += 1;
}
}
p = p->pre; //从尾部到前部进行遍历
}
//6.将原先带符号的各个数据结点都恢复为处理为正常形式,即只有头结点head->num==1||head->num==-1代表正负数或0
p = head->next;
while (p) {
p->num = abs(p->num);
p = p->next;
}
//7.处理进位情况,注意和5进行区分
//q==head->next指代链表第一个数据结点(非头结点)
while (q != head->next) {
//进行进位处理
if (q->num >= 10000) {
q->num -= 10000;
q->pre->num += 1;
}
q = q->pre;
}
if (q && q->num >= 10000) {
//产生进位情况时
struct node* t = new node;
t->next = q;
q->pre = t;
head->next = t;
t->pre = head;
t->num = q->num / 10000;
q->num = q->num % 10000;
}
//8.删除前面为0的结点
p = head->next;
//当前边出现0时删除该结点
while (p && p->num == 0) {
p->pre->next = p->next; //p结点指向数据为0 ,使P结点的前驱结点指向P的后继结点 处理P的前驱结点的next指向
if (p->next)
p->next->pre = p->pre; //处理P的后继结点的pre指针指向
p = p->next;
}
return head;
};
void display_2(struct node* head) {
if (head->next) {
struct node* p = head->next;
cout << p->num;
p = p->next;
while (p) {
printf("->%04d", p->num); //%04d保证数据输出为四位数形式,若不足则在左边补零
p = p->next;
}
cout << endl;
}
else
cout << 0 << endl;
}
int main() {
string s1, s2;
struct node *num1, *num2, *c;
cin >> s1;
cin >> s2;
reverse(s1.begin(), s1.end());
num1 = create(s1);
display(num1);
cout << endl;
reverse(s2.begin(), s2.end());
num2 = create(s2);
display(num2);
cout << endl << endl;
c = add(num1, num2);
display_2(c);
display(c);
return 0;
}
边栏推荐
- 8 — router
- 001_ layout
- Where can I find a pre training model for pytoch model training?
- 018_ rate
- 207. curriculum - graph theory, depth traversal
- [Galaxy Kirin V10] [desktop] Firefox browser settings home page does not take effect
- DDoS attacks and destructive ripple effects against online gamers
- 004_ icon
- Share the source code of the website of graduation student record
- Configure cross domain requests
猜你喜欢
![[Galaxy Kirin V10] [desktop] Firefox browser settings home page does not take effect](/img/96/e3afb2b9683cce7645afd483cc0844.png)
[Galaxy Kirin V10] [desktop] Firefox browser settings home page does not take effect
![[MySQL 05] SUSE 12 SP5 modifies the MySQL password for the first time after installing MySQL](/img/37/d24c9e5fad606d2623900ad018b6af.png)
[MySQL 05] SUSE 12 SP5 modifies the MySQL password for the first time after installing MySQL

Write this number in C

AI landing manufacturing: intelligent robots should have these four abilities

JS reverse case -rus5 logic learning

Derivation of univariate polynomial in C language

What is idempotency? Detailed explanation of four interface idempotence schemes!

CTF introductory learning (WEB direction)

搞透AQS原理(流程圖及同步隊列圖解)

Circular right shift of array elements in C language
随机推荐
Three questions from the boss
AI落地制造业:智能机器人应具备这4种能力
如何制作CSR(Certificate Signing Request)文件?
Unity2D--给动画添加关键帧并绑定事件
DDoS threat situation gets worse
Comprendre le principe AQS (organigramme et schéma de file d'attente synchrone)
[Galaxy Kirin V10] [desktop] Firefox browser settings home page does not take effect
什么是幂等性?四种接口幂等性方案详解!
26.算法常用面试题
DDoS "fire drill" service urges companies to prepare
Leetcode 46 Full arrangement (February 15, 2022)
網上炒股安全麼?炒股需要開戶嗎?
Learning C language from scratch day 026
013_ slider
[MySQL 04] sauvegarde et restauration de la base de données MySQL sous Linux en utilisant MySQL Workbench 8.0 ce
Unity2d-- add keys to animation and bind events
Some practical knowledge about PR
Simple implementation of unity object pool
The first technology podcast month will begin soon
Jenkins continuous integration environment build 8 (configure mailbox server to send build results)