数据结构:DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)
单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)
时间限制: 1S类别: DS:线性表->线性表应用
题目描述:
输入范例:
-534564675768465476586798709880985345646757684654765867987098809853456467576846547658679870988098534564675768465476586798709880985345646757684654765867987098809853456467576846547658679870988098534564675768465476586798709880985345646757684654765867987098809853456467576846547658679870988098534564675768465476586798709880985345646757684654765867987098809853456467576846547658679870988098
435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679435643754856985679
输出范例 :
-5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098
4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679,4356,4375,4856,9856,7943,5643,7548,5698,5679
-5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,6467,5768,4654,7658,6798,7098,8098,5345,2111,1392,9797,7801,8855,1455,0549,9647,0788,1412,0279,2801,6941,9155,2454,7797,0769,0089,0298,3283,1941,7242,0154,9701,8919,0069,8975,3302,2423,2241,8241,7402,0823,8219,8956,1979,2442,2723,3241,5488,8524,0124,7106,1960,1119,2742,3723,0488,6610,7824,9011,0110,1100,1419,3742,0970,1610,5911,6711,2014,9250,1400,2419
这里利用了几个关键函数:链表的逆置 比较两个链表的绝对值大小 链表的相加 输出链表
我的题解:
//DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)
#include<iostream>
#include<cstring>using namespace std;
template<class ElemType>
struct Node
{
ElemType data;
Node<ElemType>* next;
//构造函数1 用于node构造头结点
Node(Node<ElemType>* ptr = NULL)
{
next = ptr;
}
//构造函数2 用于构造其他结点
Node(const ElemType& item, Node<ElemType>* ptr = NULL)
{
next = ptr;
data = item;
} public:
ElemType getdata()
{
return data;
}
Node<ElemType>* getnext()
{
return next;
}
void set_next(Node<ElemType>* p)
{
this->next = p;
}
void set_date(ElemType num)
{
this->data = num;
}
};
template<class ElemType>
class LinkList {
private:
Node<ElemType>* head;//头指针
Node<ElemType>* tail;//尾指针 public:
//无参构造函数
LinkList()
{
head = new Node<ElemType>;
head->next = NULL;
tail = head->next;//头尾指针指向同一个内存
}
//有参构造
LinkList(const ElemType& item)
{
head = new Node<ElemType>;
tail = new Node<ElemType>;
head->next = tail = new Node<ElemType>(item);//有参构造node
}
void display()
{ //避免出现以下情况 所以我们先判断是不是就一个单0
if(head->getnext()->getdata()==0&&head->getnext()->getnext()==NULL)
{
cout<<"0";
return ;
}
if (head->getdata() == -1)
cout << "-";//如果是0就不能输出负号
//其实这样写也有问题 如果-0000 0005的就无法判断 所以我们上面解决了单0的情况
Node<ElemType>* q = head->next;
bool zeroflag = 0;
bool firstflag = 0;
//0要先特判 避免出现0 0000 0000的情况 也不行 会出现0 0000 0005 的情况无法输出
while (q->next)
{
if (q->getdata() == 0 && !zeroflag)
{
q = q->next;
continue;
}
else if(q->getdata()!=0&&!zeroflag)
{
zeroflag = 1; }
if (!firstflag)
{
cout << abs(q->data) << ",";
firstflag = 1;
}
else
printf("%04d,", abs(q->data));
q = q->next; }
if (q == head->next)//只有一位特判
cout << abs(q->data);
else
{
if (!firstflag)
{
cout << abs(q->data); }
else
{
if (!zeroflag)
{
cout << abs(q->data); }
else
{
printf("%04d", abs(q->data));
} } } cout << endl;
}
int size()
{
if (head->next == NULL)
return 0;
int len = 0;
Node<ElemType>* q;
q = head->next;
while (q)
{
len++;
q = q->next;
}
return len;
}
void push_back(ElemType x)
{
Node<ElemType>* q = new Node<ElemType>;//新建结点
q->data = x;
q->next = NULL;
if (size() == 0)
{
head->next = q; }
else
{
tail->next = q; }
tail = q; }
Node<ElemType>* get_front(Node<ElemType>* p)
{//获取一个指针的上一个,头指针和非法指针会报错.
Node<ElemType>* q;
q = head->next;
while (q->next != NULL)
{
if (q->next == p)
return q;
q = q->next;
}
}
Node<ElemType>* get_next(Node<ElemType>* p)
{
return p->next;
}
Node<ElemType>* get_address(int i)//获取指定下标的地址
{
Node<ElemType>* q;
q = head->next;
while (i--)
q = q->next;
return q;
}
ElemType at(int i)
{
Node<ElemType>* q = get_address(i);
return q->data;
}
bool del_p(Node<ElemType>* p)//传入一个指针 删除
{
if (size() == 0)
return false;
if (tail->next == NULL)//如果只有一个元素
{
if (p == tail)//如果这个指针是那个唯一的指针
{
delete tail;
tail = NULL;
return true;
}
else
return false;//如果不是 }
if (p == tail)//如果删除的是尾指针
{
Node<ElemType>* q = get_front(p);
q->next = NULL;
tail = q;
delete p;
return true;
}
//其他的
Node<ElemType>* q = get_front(p);
q->next = p->next;
delete p;
return true; }
bool del(int i)//删除指定位置的元素
{
return del_p(get_address(i));
}
Node<ElemType>* get_head()
{
return head;
}
Node<ElemType>* get_tail()
{
return tail;
}
void set_head(Node<ElemType>* p)
{ head = p;
}
void set_tail(Node<ElemType>* p)
{
tail = p;
}
void ListReverse()
{
Node<ElemType>* a, * b, * temp;
a = head->getnext();
ElemType datas = head->getdata();
temp = NULL;
b = NULL;
bool flag = 0;//设置尾指针的标志
while (a)
{
b = a;
a = a->getnext();
b->set_next(temp);
if (!flag)
{
tail = b;
flag = 1;
}
temp = b;
}
Node<ElemType>* newhead = new Node<ElemType>;
newhead->set_next(b);
newhead->set_date(datas);
head = newhead; }
}; //从长整数的低位开始拆分(4位为一组,即不超过9999的非负整数),依次存放在单链表的每个结点的数据域中;
//头结点的数据域存放正负数标志(正数或0:1,负数:-1)。
template<class ElemType>
void Input_Int_Division(LinkList<ElemType>& L, string& str, int& length)
{
Node<ElemType>* head = L.get_head();
bool zhengfu_flag = 0;//记录正负的flag
int l = str.length();
if (str[0] == '-')//先特判正负数
{ zhengfu_flag = 1;
head->set_date(-1); }
else
{
head->set_date(1);
}
int i = 0;
if (zhengfu_flag)
i = 1;
int t0 = l % 4;
if (t0 == 0)
t0 = 4;
int t = 0;//记录位数
int num = 0;//存四位数
bool changeflag = 0;//判断标志 判断是否有进行第一次
for (; i < t0; ++i)
{
num = num * 10 + (str[i] - '0');
changeflag = 1;
}
if (changeflag)
{
length++;//记录长度
L.push_back(num);
num = 0;
} for (; i < str.length(); ++i)
{ num = num * 10 + (str[i] - '0');
t++;
if (t == 4)
{
length++;//记录长度
L.push_back(num);
t = 0;
num = 0;
}
}
//L.display();
}
//两个长整数的 绝对值 大小比较
//(x>y 返回值为1;x<y 返回值为2;x=y 返回值为0;)
template<class ElemType>
int Two_LongNum_Compare(LinkList<ElemType>& A, LinkList<ElemType>& B, const int& len_A, const int& len_B)
{
Node<ElemType>* head1 = A.get_head();
Node<ElemType>* head2 = B.get_head(); //正数的情况 先看长度
if (len_A > len_B)
{
return 1;
}
else if (len_A < len_B)
{
return 2;
}
else if (len_A == len_B)
{
Node<ElemType>* a, * b;
a = head1->getnext();
b = head2->getnext();
while (a)
{
if (a->getdata() > b->getdata())
return 1;
else if (a->getdata() < b->getdata())
return 2;
else
a = a->getnext(), b = b->getnext();
}
return 0;
} }
template<class ElemType>
void swaps(LinkList<ElemType>& a, LinkList<ElemType>& b)
{
LinkList<ElemType>temp = a;
a = b;
b = temp;
}
template<class ElemType>
void Listadds(LinkList<ElemType>& a, LinkList<ElemType>& b, int& la, int& lb)
{
Node<ElemType>* x, * y; int ans = 0;
if (la < lb)
{
//swap一下两个
swaps(a, b);
int temp = la;
la = lb;
lb = temp;
}
x = a.get_head()->getnext();
y = b.get_head()->getnext();//两个指针的创建必须放在 交换判断之后
int m = a.get_head()->getdata();//m n 存储符号
int n = b.get_head()->getdata();//存储符号也必须放在交换判断之后 //第一步 判断结果的最高位//!必须再加法前进行 !!因为a会随着加法而改变 引用传递
bool flag = 0;//标记元素
int comp = Two_LongNum_Compare(a, b, la, lb); while (y)//先把每一位结点的数值加起来
{
ans = x->getdata() * m + y->getdata() * n;
x->set_date(ans);
x = x->getnext();
y = y->getnext();
}
//把长的位都化成同号的 不然接下来进位会出问题
while (x)
{
x->set_date(x->getdata() * m);
x = x->getnext();
}
//再做进位处理 if (comp == 1)
{
flag = 1;
}
//第二步 开始逐位遍历
x = a.get_head()->getnext();
int zheng_fu = 0;//判断正负的符号
if (flag)
zheng_fu = a.get_head()->getdata();
else
zheng_fu = b.get_head()->getdata();
if (zheng_fu > 0)//分正负两种情况 先看是正的
{
a.get_head()->set_date(1);//定最高位符号
while (x->getnext())//最后一个结点先不遍历 最后单独讨论
{
if (x->getdata() > 9999)
{
x->set_date(x->getdata() - 10000);
x->getnext()->set_date(x->getnext()->getdata() + 1);
//下一位就加一
}
else if (x->getdata() < 0)
{
x->set_date(x->getdata() + 10000);
x->getnext()->set_date(x->getnext()->getdata() - 1);
}
x = x->getnext();
}
//讨论最后一位 是否要进位
if (x->getdata() > 9999)
{
x->set_date(x->getdata() - 10000);
a.push_back(1);
}
}
else //讨论负数的情况
{
a.get_head()->set_date(-1);//定最高位符号
while (x->getnext())//最后一个结点先不遍历 最后单独讨论
{
if (x->getdata() < -9999)
{
x->set_date(x->getdata() + 10000);
x->getnext()->set_date(x->getnext()->getdata() - 1);
//下一位就加一
}
else if (x->getdata() > 0)
{
x->set_date(x->getdata() - 10000);
x->getnext()->set_date(x->getnext()->getdata() + 1);
}
x = x->getnext();
}
//讨论最后一位 是否要进位
if (x->getdata() < -9999)
{
x->set_date(x->getdata() + 10000);
a.push_back(1);
}
}
} int main()
{
LinkList<int>head1, head2;
string str1, str2;
getline(cin, str1);
getline(cin, str2);
int la = str1.length();
int lb = str2.length();
if (str1[0] == '-')
la -= 1;
if (str2[0] == '-')
lb -= 1;
int length1 = 0;
int length2 = 0;
Input_Int_Division(head1, str1, length1);
Input_Int_Division(head2, str2, length2);
head1.display();
head2.display();
cout << endl;
head1.ListReverse();
head2.ListReverse();
Listadds(head1, head2, la, lb);
head1.ListReverse();
head1.display();
//swaps(head1, head2);
//head1.display();
//head2.display();
//cout << endl;
//int comp = Two_LongNum_Compare(head1, head2, length1, length2);
//cout << comp;
//cout << length<<endl;
//head.ListReverse();
//head.display(); return 0; }
数据结构:DHUOJ 单链表ADT模板应用算法设计:长整数加法运算(使用单链表存储计算结果)的更多相关文章
- Python数据结构与算法设计总结篇
1.Python数据结构篇 数据结构篇主要是阅读[Problem Solving with Python]( http://interactivepython.org/courselib/static ...
- Python数据结构与算法设计(总结篇)
的确,正如偶像Bruce Eckel所说,"Life is short, you need Python"! 如果你正在考虑学Java还是Python的话,那就别想了,选Pytho ...
- 算法设计与分析 - 李春葆 - 第二版 - html v2
1 .1 第 1 章─概论 1.1.1 练习题 1 . 下列关于算法的说法中正确的有( ). Ⅰ Ⅱ Ⅲ Ⅳ .求解某一类问题的算法是唯一的 .算法必须在有限步操作之后停止 .算法 ...
- 《数据结构与算法之美》 <05>链表(下):如何轻松写出正确的链表代码?
想要写好链表代码并不是容易的事儿,尤其是那些复杂的链表操作,比如链表反转.有序链表合并等,写的时候非常容易出错.从我上百场面试的经验来看,能把“链表反转”这几行代码写对的人不足 10%. 为什么链表代 ...
- 正整数构成的线性表存放在单链表中,编写算法将表中的所有的奇数删除。(C语言)
/* 正整数构成的线性表存放在单链表中,编写算法将表中的所有的奇数删除 */ #include <stdio.h> #include <stdlib.h> typedef st ...
- 数据结构作业——P53页算法设计题(7):原地逆转链表
一. 题目描述: 设计一个算法,将链表中所有结点的链接方向"原地"逆转,即要求仅利用原表的存储空间,换句话说,要求算法的空间复杂度为O(1). 二.算法设计 #include< ...
- 数据结构:DHU顺序表ADT模板设计及简单应用:找匹配
顺序表ADT模板设计及简单应用:找匹配 时间限制: 1S类别: DS:线性表->线性表应用 问题描述: 输入范例: 100000100000 99999 99998 99997 99996 99 ...
- 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法
"为什么这个功能用不了?" 程序员:"清一下缓存" 上篇洞悉系列文章给大家详细介绍了MySQL的存储内幕:洞悉MySQL底层架构:游走在缓冲与磁盘之间.既然聊过 ...
- 【算法设计与分析基础】25、单起点最短路径的dijkstra算法
首先看看这换个数据图 邻接矩阵 dijkstra算法的寻找最短路径的核心就是对于这个节点的数据结构的设计 1.节点中保存有已经加入最短路径的集合中到当前节点的最短路径的节点 2.从起点经过或者不经过 ...
随机推荐
- Linux中查看进程与日志
转至:https://www.cnblogs.com/dengxiaoning/p/13336778.html Linux尽管使用频繁,仍然每次都还是需要到处去找相关的命令,如进程,日志之类的,既然这 ...
- Linux 启动、停止、重启jar包脚本
转至:https://www.cnblogs.com/foolash/p/13824647.html startOrStropJar.sh #!/bin/bash #这里可替换为你自己的执行程序,其他 ...
- Element-UI tree 组件 点击后高亮显示的样式修改(背景色)
感觉默认的高亮背景色颜色太浅,修改一下: .el-tree-node:focus > .el-tree-node__content { background-color: #ccc !impor ...
- CentOS8安装Geant4笔记(一):Geant4介绍、编译和安装
前言 在服务器CentOS8.2上安装geant4软件. GEANT4 介绍 Geant4 是一个用于模拟粒子穿过物质的工具包.其应用领域包括高能.核物理和加速器物理,以及医学和空间科学研 ...
- LeetCode-024-两两交换链表中的节点
两两交换链表中的节点 题目描述:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例说明请见LeetCode官网. 来源:力 ...
- 在pycharm中批量插入表数据、分页原理、cookie和session介绍、django操作cookie
昨日内容回顾 ajax发送json格式数据 ''' 1. urlencoded 2. form-data 3. json ''' 1. ajax $.ajax({ data: JSON.stringi ...
- thinkphp 框架自带搜索+分页+搜索标红
..........控制器方法 public function index() { //接受搜索关键字 $word=input('word'); $where=[]; if (!empty($word ...
- PHP pdf转png windows版本
链接:https://pan.baidu.com/s/1Bli-2HkucRTYTeujkcsmjg&shfl=sharepset 提取码:2une 1.php_imagick扩展 (1)下载 ...
- phpStudy windows服务器下安装,以及外网不能访问的问题
废话不多说,超简单 1.下载phpstudy软件包http://phpstudy.php.cn/官网进行下载 2.安装,下一步式傻瓜安装 3.配置域名: 打开hosts文件,添加 然后然后访问域名就可 ...
- Github又悄悄升级了,这次的变化是大文件的存储方式
目录 简介 LFS和它的安装 LFS的使用 从LFS中删除文件 从LFS中拉取代码 转换历史数据到LFS 总结 简介 github是大家常用的代码管理工具,也被戏称为世界上最大的程序员交友网站,它的每 ...