链表问题——长整数加法运算题解【双向链表】

news2024/7/30 8:07:43

长整数加法运算

在这里插入图片描述

问题描述

假设2个任意长度的整数x、y分别用链表A和B存储,现要求设计一个算法,实现x+y。计算结果存储在链表C中。

说明:

链表A、B、C可以是单向链表或双向链表,但由于A和B输出时需要从头至尾遍历,而做加法时需要从尾至头遍历,因此推荐使用双向链表存储。

链表的每个结点的数据域可以选择以下三种设计方式:

(1)链表的每个结点存储长整数的一位(不推荐);

(2)链表的每个结点从长整数的低位开始拆分(4位为一组,存到一个结点中,即结点的数据域为不超过9999的非负整数),依次存放在链表的每个结点;

(3)链表的每个结点从长整数的低位开始拆分(4位为一组,存到一个结点中,即结点的数据域为1-4位字符串),依次存放在链表的每个结点。

可利用头结点的数据域存放正负数标志(正数或0:1(“1”),负数:-1(“-1”))。

输入说明

第一行:长整数x

第二行:长整数y

输出说明

第一行:格式化后的长整数x(从低位到高位每4位用","分开)

第二行:格式化后的长整数y(从低位到高位每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

题解

思路

  • 输出43,5643,7548,5698,5679样式用string拼接实现。
  • 在计算中,关键是如何判断最终结果的负号,或者说A,B到底哪一个绝对值更大,这将决定异号时谁减谁。

我的做法:

  • A、B逆序模拟加减法计算,结果头插到新链表

  • 分步完成计算,第一步,A、B每个结点分别添置符号先不考虑进位,暴力相加(减法转为加负数,允许结果绝对值超过 1w)

  • 根据结果头部4位数去决定符号【头部的数字最大,如何借位进位都不可能改变正负】,--,++,+-,-+四种情况统一了,第二步如下两条:

  • 在同号相加计算中,考虑进位溢出,更要考虑头部4位是否溢出(>=10000

  • 在异号相加【减法】计算中,考虑与头部符号异号的那组数的符号纠正,考虑向前借位。

  • 在输出中,关键是如何判断,是否需要添有效0,比如:1,0000,避免无效0的出现,比如:0001000,0000,0000

代码实现

#include<iostream>
#include<cstring>
#include<stack>
#include<iomanip>

using namespace std;

const int W =10000;
typedef struct node
{
    int data;
    struct node *next;
    struct node* pre;
} link;
int main()
{
    string a,b;
    cin>>a>>b;
    // 预处理,补齐符号位,便于开头逗号处理。 比如正好四位数 会遇到 “,1234”开头添置逗号的情况。
    if(a[0] != '-')a ="+"+a;
    if(b[0] != '-')b ="+"+b;
    string new_a="",new_b="";
    int ct =0;
    for(int i=a.length()-1; i>=0; i--)
    {
        if(a[i] >='0' && a[i]<= '9')
        {
            new_a =to_string(a[i])+new_a;
            ct++;
            if(ct == 4)
            {
                new_a =","+new_a;
                ct =0;
            }

        }
        else // meet + 、-
        {
            if(new_a[0] ==',')new_a.erase(0,1);
            if(a[i] == '-')new_a =to_string(a[i])+new_a;

        }

    }
    cout<<new_a<<endl;
    ct=0;
    for(int i=b.length()-1; i>=0; i--)
    {
        if(b[i] >='0' && b[i]<= '9')
        {
            new_b =to_string(b[i]) + new_b;
            ct++;
            if(ct == 4)
            {
                new_b ="," +new_b;
                ct =0;
            }
        }
        else
        {
            if(new_b[0] ==',')new_b.erase(0,1);//去掉开头误加上的逗号。
            if(b[i] == '-')new_b =to_string(b[i])+new_b;//符号位打印只需要负号
        }

    }

    cout<<new_b<<endl;
    cout<<endl;
    //
    link* A,*B;
    A = new link;
    B = new link;
    create_dob_link(A,new_a);
    create_dob_link(B,new_b);
    // calculate A + B
    link *C = new link;
    C->next = NULL;
    C->pre = NULL;

    calculate(A,B,C);
    print_link(C);
}

创建双向链表函数

void create_dob_link(link *head,string data)
{

    link *tail =head;
    tail->next = NULL;
    tail->pre = NULL;
    //judge + -
    if(data[0] == '-')
    {
        head->data  =-1;
        data.erase(0,1);

    }
    else head->data = 1;
    //additional ','
    data +=",";

    //
    int res=0;
    for(int i=0; i<data.length(); i++)
    {
        if(data[i] >='0' && data[i]<='9')//condition: number
        {
            res =res*10 + data[i]-'0';

        }
        else  //condition:,
        {

            link * p = new link;
            p->data = res;
            p->next = tail->next;
            tail->next = p;
            p->pre =tail;
            tail = p;
            //initial
            res =0;
        }
    }
}

char to string 函数(挺笨的,但有效)

string只能拼接字符串,无法拼接字符。

string to_string(char x)
{
    string res;
    if(x == '0')res="0";
    else if(x == '1')res="1";
    else if(x == '2')res="2";
    else if(x == '3')res="3";
    else if(x == '4')res="4";
    else if(x == '5')res="5";
    else if(x == '6')res="6";
    else if(x == '7')res="7";
    else if(x == '8')res="8";
    else if(x == '9')res="9";
    else if(x == '-')res="-";

    return res;
}

头插法构建结果链表

void head_insert_link(link *C,int data)
{
    link * p = new link;
    p->data = data;
    p->next = C->next;
    C->next = p;
    p->pre = C;
    if(p->next)p->next ->pre = p;

}

结果打印函数(※)

void print_link(link *head)
{

    int f=false;//判断是否遇到了有效数字
    int ff =false;//判断当前的0是否为有效数字
    link *p=head->next;
    if(head->data < 0)cout<<"-";
    while(p)
    {
        if(p->data != 0)
        {
            //print
            if(ff)cout<<setfill('0')<<setw(4)<<abs(p->data);
            else cout<<abs(p->data);//condition: 1,0001  需要补有效0 
            f =true;
        }
        else   //condition: 1,0000,0000 需要补有效0 
        {
            if(f ==true && p->data == 0)cout<<"0000";
        }
//
        if(f && p->next)
        {
            cout<<",";
            //只要有逗号,0左侧一定会有数,后面遇到的数就是需要有效0。
            ff =true;
        }
        p=p->next;
    }
    //condition: 000,0000 纯零结果
    if(f == false)cout<<"0";
    cout<<endl;
}

长整数加减计算函数(※※※)

void calculate(link * A, link * B,link * C)
{
// part 1:先不考虑进位
    link *pa=A->next, * pb=B->next;
    while(pa->next)pa = pa->next;
    while(pb->next)pb = pb->next;

    while(pa !=A && pb != B)
    {
        //with +- maybe out range
        int res = pa->data * A->data + pb->data * B->data;
        head_insert_link(C,res);
        //next
        pa=pa->pre;
        pb=pb->pre;
    }

    while(pa != A)
    {
        int res = pa->data * A->data ;
        head_insert_link(C,res);
        pa=pa->pre;
    }
    while(pb != B)
    {
        int res = pb->data * B->data;
        head_insert_link(C,res);
        pb=pb->pre;

    }
//part 2:
//由顶部四位决定最终取值正负
    link * p =C->next;
    while(p->next)p=p->next;

    if(p && p->data < 0)C->data =-1;
    else C->data =1;
    while(p->pre != C)
    {
		//消除异号
        if(p->data * C->data < 0)
        {
            if(p->data <0)
            {
                p->data +=W;
                p->pre->data -=1;//头部为正值,借位,前面少了个1
            }
            else if(p->data >0)
            {
                p->data -=W;
                p->pre->data+=1;//头部为负值,借位,前面少了个-1,  对负数来说+1就是少了。
            }
           // else 0000 pass.
        }
		//同号进位,(未考虑头部溢出),while(p->pre != C) 就决定了 p是处理不到头部4位就结束了。下面补上了这个溢出处理。
        if(abs(p->data)>= W )
        {
            if(p->data > 0)
            {
                p->data -=W;
                p->pre->data +=1;
            }
            else
            {
                p->data +=W;
                p->pre->data +=-1;
            }
        }
        p=p->pre;
    }
    if(abs(p->data)>=W)//补充,考虑头部溢出
    {
        p->data %=W;
        head_insert_link(C,1);

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/730052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git提交项目到服务器上

目录 第一步&#xff1a;git status第二步&#xff1a;git pull第三步&#xff1a;git status第四步&#xff1a;git add第五步&#xff1a;git commit第六步&#xff1a;git push 第一步&#xff1a;git status git status 看一下你这个项目里&#xff0c;修改过什么公版的东西…

性能优化(一)JMeter使用

简介&#xff1a; jmeter 是 apache 公司基于 java 开发的一款开源压力测试工具&#xff0c;体积小&#xff0c;功能全&#xff0c;使用方便&#xff0c;是一个比较轻量级的测试工具&#xff0c;使用起来非常简 单。因为 jmeter 是 java 开发的&#xff0c;所以运行的时候必须…

Django_模板(四)

目录 一、模板 创建模板文件 定义模板 视图调用模板 简写视图调用的模板 二、去除模板中的硬编码 URL 三、为 URL 名称添加命名空间 四、生成模板渲染后的静态文件 源码等资料获取方法 一、模板 如何向请求者返回一个漂亮的页面呢&#xff1f; 肯定需要用到html、css…

多元分类预测 | Matlab基于鲸鱼优化深度置信网络(WOA-DBN)的分类预测,多输入单输出模型,多特征输入模型,WOA-DBN分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab基于鲸鱼优化深度置信网络(WOA-DBN)的分类预测,多输入单输出模型,多特征输入模型,WOA-DBN分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语…

Unity3d的智力拼图小游戏

Unity3d的智力拼图小游戏 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88015674

关于async/await

async/await是什么&#xff1f; 简单来说async/await是Promise的语法糖&#xff0c;async是异步的意思&#xff0c;await是等待的意思。async function 声明一个函数里面可能有异步代码需要执行&#xff0c;await则可以认为是等待一个异步方法执行完成。 async/await的用法 …

创建台虚拟机并安装上window10系统(NETBASE 第一课)

虚拟机&#xff08;Virtual Machine&#xff09;是一种基于软件的模拟技术&#xff0c;它可以将一台物理计算机模拟成多个虚拟计算机运行不同的操作系统和应用程序&#xff0c;从而实现资源的虚拟化和隔离。在虚拟机中&#xff0c;每个虚拟计算机都拥有自己的独立的操作系统和应…

MySQL基础篇第1章(数据库概述)

文章目录 1、为什么要使用数据库2、数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库与数据库管理系统的关系2.3 常见的数据库管理系统排名2.4 常见的数据库介绍 3、MySQL介绍3.1 概述3.2 MySQL发展史重大事件3.3 关于MySQL 8.03.4 Oracle VS MySQL 4、RDBMS 与 非RDBMS4…

java的void和Void

java 函数如果什么类型的值也不需要返回&#xff0c;用关键字void。 而Void是一个类&#xff0c;是一个不能实例化的占位符类&#xff0c;它持有对一个类对象的引用&#xff0c;这个类对象代表java关键字void。 如果函数返回值是Void&#xff0c;那么函数必须明确返回null。 J…

将 jar 构建成 docker 镜像实例

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

Java的数据结构

目录 数据结构: 1,数组 2,链表 3,哈希表 4,队列 5,堆 6,栈 7,树 8,图 数据结构: 1,数组 优点: 查找元素的速度很快; 按照索引来遍历数组的速度也很快。 缺点: 数组大小无法改变,一旦创建就无法扩容; 数组只能存储一种数据类型的数据; 插入、修改、删除时比较麻烦&…

1-软件测试答疑

目录 1.什么是软件测试&#xff1f; 1.1.生活中测试场景 1.2.软件测试定义 1.3.为什么要有软件测试&#xff1f;/重要性 1.4.练习&#xff1a;软件系统登录功能如何测试&#xff1f; 1.5.软件测试的特点 2.软件测试和开发的区别 2.1.工作内容 2.2.技能要求 2.3.难易程…

spring监视器actuator

引入依赖 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId><…

第五章 神经网络与手写体识别

文章目录 第五章 神经网络5.1神经元模型5.2感知机与多层网络5.3误差逆传播算法5.4全局最小和局部最小5.5其他常见神经网络5.5.1RBF网络5.5.2ART网络5.5.3SOM网络5.5.4级联相关网络5.5.5Elman网络5.5.6Boltzmann机 5.6深度学习5.7实验&#xff1a;手写数字识别 第五章 神经网络 …

【QT】——QJson类的使用

目录 1.Json的格式 1.1.Json数组 1.2.Json对象 2.QJson 2.1 QJsonObject 2.2 QJsonValue 2.3 QJsonArray 2.4 QJsonDocument 3.示例 3.1 写操作 3.2 读操作 1.Json的格式 Json的基本概念 Json 是一种数据格式&#xff0c;和语言无关&#xff0c;在什么语言中都可以…

Host is not allowed to connect to this MySQL server

问题:win10 系统上运行node&#xff0c;运行提示&#xff1a;Host is not allowed to connect to this MySQL server。 在windows10上面装完MySQL8.0.28&#xff0c;发现本地可以使用Navicat进行连接 &#xff0c;但是在vue项目中调用node接口连接mysql却报错Host is not all…

Python学习笔记(十五)————文件操作相关

目录 1&#xff09;文件编码 2&#xff09; 文件的读取 ①open()打开函数 ② mode常用的三种基础访问模式 ③读操作相关方法 read()方法&#xff1a; readlines()方法&#xff1a; readline()方法&#xff1a;一次读取一行内容 for循环读取文件行 close() 关闭文件对象 wi…

simulink 结构体 bus creator

目录 结构体创建 bus creator 结构体引用Bus Selector 结构体赋值Bus Assignment 结构体对象 Bus 结构体数组打包Vector Concatenate 结构体数据存文件 结构体创建 bus creator 结构体引用Bus Selector 结构体赋值Bus Assignment 结构体对象 Bus 结构体数组打包Vector Co…

【MYSQL高级】Mysql找出执行慢的SQL【慢查询日志使用与分析】

分析慢SQL的步骤 慢查询的开启并捕获&#xff1a;开启慢查询日志&#xff0c;设置阈值&#xff0c;比如超过5秒钟的就是慢SQL&#xff0c;至少跑1天&#xff0c;看看生产的慢SQL情况&#xff0c;并将它抓取出来explain 慢SQL分析show Profile。&#xff08;比explain还要详细…

手搭手入门Spring boot+Mybatis+达梦数据库(国产数据库)

环境介绍 软件版本DM数据库dm8_20230418_x86_win_64IDEAIntelliJ IDEA 2022.2.1JDK1.8Spring Boot2.7.13mybatis2.3.1 达梦&#xff08;国产数据库&#xff09;可以将数据库名和表名自动转换为大写(注意&#xff01;&#xff01;创建达梦数据库实例的时候配置是否有勾选大小写…