【模板小程序】 十进制大数相乘(正数、负数、0均可),包含合法性检查

  1 /*
  2 本程序说明:
  3 
  4 大数乘法(模拟乘法操作,取其中一个字符串,每一位分别相乘,最后移位加起来)
  5 
  6 时间复杂度:O(k1*k2),k1和k2分别为两字符串长度
  7 空间复杂度:O(1)
  8 
  9 */
 10 
 11 #include <iostream>
 12 #include <string>
 13 #include <algorithm>
 14 #include <vector>
 15 
 16 using namespace std;
 17 
 18 //输入数据合法性检查,数字必须在0-9范围内
 19 bool IsVaild(const string& num1,const string& num2)
 20 {
 21     for(size_t i=0;i<num1.length();++i)
 22     {
 23         if(0==i && '-'==num1[0] && ++i<num1.length()){};//首位可以是'-',这里直接加i,继续判断
 24         if(!(num1[i]>='0' && num1[i]-'0'<='9'))
 25             return false;
 26     }
 27     for(size_t i=0;i<num2.length();++i)
 28     {
 29         if(0==i && '-'==num2[0] && ++i<num2.length()){};//首位可以是'-',这里直接加i,继续判断
 30         if(!(num2[i]>='0' && num2[i]-'0'<='9'))
 31             return false;
 32     }
 33     return true;
 34 }
 35 
 36 //辅助函数:符号为两正和两负时调用,这里的num1和num2不包含符号位
 37 string _greatNumberAdd(string num1,string num2)
 38 {
 39     const size_t len1=num1.length();
 40     const size_t len2=num2.length();
 41     const size_t n=len1>len2 ? len1 :len2;
 42     reverse(num1.begin(),num1.end());
 43     reverse(num2.begin(),num2.end());
 44 
 45     string result;
 46     int carry=0;//进位
 47     for(size_t i=0;i<n;++i)
 48     {
 49         const int num1i = i<len1 ? num1[i]-'0' :0;
 50         const int num2i = i<len2 ? num2[i]-'0' :0;
 51         const int val   = (num1i+num2i+carry)%10;
 52         carry=(num1i+num2i+carry)/10;
 53         result.insert(result.begin(),val+'0');
 54     }
 55     if(1==carry)//若最前面有进位,则插入'1'
 56         result.insert(result.begin(),'1');
 57 
 58     return result;
 59 }
 60 
 61 //大数相乘辅助函数(执行实际的乘法)
 62 string _greatNumberMulti(string num1,string num2)
 63 {
 64     const size_t len1=num1.length();
 65     const size_t len2=num2.length();
 66 
 67     reverse(num1.begin(),num1.end());
 68     reverse(num2.begin(),num2.end());
 69 
 70     string result;
 71     for(size_t i=0;i<len1;++i)
 72     {
 73         string tmp_Add;
 74         int carry=0;//进位
 75         for(size_t j=0;j<len2;++j)
 76         {
 77             const int val   = ((num1[i]-'0')*(num2[j]-'0')+carry)%10;
 78             carry=((num1[i]-'0')*(num2[j]-'0')+carry)/10;
 79             tmp_Add.insert(tmp_Add.begin(),val+'0');
 80         }
 81         if(carry>0)//若最前面有进位,则插入
 82             tmp_Add.insert(tmp_Add.begin(),carry+'0');
 83         for(size_t _=0;_<i;++_)//模拟乘法操作的补零
 84             tmp_Add+="0";
 85         result=_greatNumberAdd(result,tmp_Add);
 86     }
 87     return result;
 88 }
 89 
 90 //大数相乘入口,先判断符号(两正、两负、一正一负),再调用辅助函数
 91 string greatNumberMulti(string num1,string num2)
 92 {
 93     /*******************判断正负号开始***********************/
 94     int flag=0;//0:两正;1:一正一负;2:两负
 95     if('-'==num1[0])
 96     {
 97         num1.erase(num1.begin());
 98         flag=1;
 99     }
100     if('-'==num2[0])
101     {
102         num2.erase(num2.begin());
103         //若1==flag,则说明num1也为负数,即为两负;否则只有num2为负数
104         flag= (1==flag) ? 2 : 1;
105     }
106     /*******************判断正负号结束***********************/
107 
108     string result=_greatNumberMulti(num1,num2);
109 
110     int firstIndex_notEqualTo_0=0;//找出第一个不为0的位置(如果前面均为0,则抹去)
111     for(;firstIndex_notEqualTo_0<result.length();++firstIndex_notEqualTo_0)
112     {
113         if(result[firstIndex_notEqualTo_0]!='0')
114             break;
115     }
116     if(firstIndex_notEqualTo_0>0)//(如果前面均为0,则抹去)
117         result.erase(0,firstIndex_notEqualTo_0);
118     if(result.empty())//如果两个数相加结果为0,最后处理完就为空了,因此直接输出"0"
119     {
120         result="0";
121         return result;
122     }
123 
124     if(1==flag)//若一正一负且结果不为0,在最前面添加'-'
125         result.insert(result.begin(),'-');
126 
127     return result;
128 }
129 
130 int main()
131 {
132     string num1,num2;
133     while(cin>>num1>>num2)
134     {
135         if(IsVaild(num1,num2))
136             cout<<greatNumberMulti(num1,num2)<<endl;
137         else
138             cout<<"输入数据不合法"<<endl;
139     }
140     return 0;
141 }

 

以下是调试版本(保存乘法每一步的结果),因此空间复杂度高一点:

  1 /*
  2 本程序说明:
  3 
  4 大数乘法(模拟乘法操作,取其中一个字符串,每一位分别相乘,最后移位加起来)
  5 
  6 时间复杂度:O(k1*k2),k1和k2分别为两字符串长度
  7 空间复杂度:O(k),k为字符串num1的长度
  8 
  9 */
 10 
 11 #include <iostream>
 12 #include <string>
 13 #include <algorithm>
 14 #include <vector>
 15 
 16 using namespace std;
 17 
 18 //输入数据合法性检查,数字必须在0-9范围内
 19 bool IsVaild(const string& num1,const string& num2)
 20 {
 21     for(size_t i=0;i<num1.length();++i)
 22     {
 23         if(0==i && '-'==num1[0] && ++i<num1.length()){};//首位可以是'-',这里直接加i,继续判断
 24         if(!(num1[i]>='0' && num1[i]-'0'<='9'))
 25             return false;
 26     }
 27     for(size_t i=0;i<num2.length();++i)
 28     {
 29         if(0==i && '-'==num2[0] && ++i<num2.length()){};//首位可以是'-',这里直接加i,继续判断
 30         if(!(num2[i]>='0' && num2[i]-'0'<='9'))
 31             return false;
 32     }
 33     return true;
 34 }
 35 
 36 //辅助函数:符号为两正和两负时调用,这里的num1和num2不包含符号位
 37 string _greatNumberAdd(string num1,string num2)
 38 {
 39     const size_t len1=num1.length();
 40     const size_t len2=num2.length();
 41     const size_t n=len1>len2 ? len1 :len2;
 42     reverse(num1.begin(),num1.end());
 43     reverse(num2.begin(),num2.end());
 44 
 45     string result;
 46     int carry=0;//进位
 47     for(size_t i=0;i<n;++i)
 48     {
 49         const int num1i = i<len1 ? num1[i]-'0' :0;
 50         const int num2i = i<len2 ? num2[i]-'0' :0;
 51         const int val   = (num1i+num2i+carry)%10;
 52         carry=(num1i+num2i+carry)/10;
 53         result.insert(result.begin(),val+'0');
 54     }
 55     if(1==carry)//若最前面有进位,则插入'1'
 56         result.insert(result.begin(),'1');
 57 
 58     return result;
 59 }
 60 
 61 //大数相乘辅助函数(执行实际的乘法)
 62 vector<string> _greatNumberMulti(string num1,string num2)
 63 {
 64 
 65     const size_t len1=num1.length();
 66     const size_t len2=num2.length();
 67 
 68     reverse(num1.begin(),num1.end());
 69     reverse(num2.begin(),num2.end());
 70 
 71     vector<string> result;
 72     for(size_t i=0;i<len1;++i)
 73     {
 74         string tmp_Add;
 75         int carry=0;//进位
 76         for(size_t j=0;j<len2;++j)
 77         {
 78             const int val   = ((num1[i]-'0')*(num2[j]-'0')+carry)%10;
 79             carry=((num1[i]-'0')*(num2[j]-'0')+carry)/10;
 80             tmp_Add.insert(tmp_Add.begin(),val+'0');
 81         }
 82         if(carry>0)//若最前面有进位,则插入
 83             tmp_Add.insert(tmp_Add.begin(),carry+'0');
 84 
 85         result.insert(result.begin(),tmp_Add);
 86     }
 87 
 88     return result;
 89 }
 90 
 91 //大数相乘入口,先判断符号(两正、两负、一正一负),再调用辅助函数
 92 string greatNumberMulti(string num1,string num2)
 93 {
 94     /*******************判断正负号开始***********************/
 95     int flag=0;//0:两正;1:一正一负;2:两负
 96     if('-'==num1[0])
 97     {
 98         num1.erase(num1.begin());
 99         flag=1;
100     }
101     if('-'==num2[0])
102     {
103         num2.erase(num2.begin());
104         //若1==flag,则说明num1也为负数,即为两负;否则只有num2为负数
105         flag= (1==flag) ? 2 : 1;
106     }
107     /*******************判断正负号结束***********************/
108 
109     vector<string> result=_greatNumberMulti(num1,num2);
110 
111 
112     string result_output;
113 
114     for(int i=0;i<result.size()-1;++i)//模拟乘法操作的补零
115     {
116         for(int tmp=0;tmp<result.size()-1-i;++tmp)
117             result[i]+="0";
118     }
119     for(int i=0;i<result.size();++i)
120     {
121         result_output=_greatNumberAdd(result_output,result[i]);
122     }
123 
124     int firstIndex_notEqualTo_0=0;//找出第一个不为0的位置(如果前面均为0,则抹去)
125     for(;firstIndex_notEqualTo_0<result_output.length();++firstIndex_notEqualTo_0)
126     {
127         if(result_output[firstIndex_notEqualTo_0]!='0')
128             break;
129     }
130     if(firstIndex_notEqualTo_0>0)//(如果前面均为0,则抹去)
131         result_output.erase(0,firstIndex_notEqualTo_0);
132     if(result_output.empty())//如果两个数相加结果为0,最后处理完就为空了,因此直接输出"0"
133     {
134         result_output="0";
135         return result_output;
136     }
137 
138     if(1==flag)//若一正一负且结果不为0,在最前面添加'-'
139         result_output.insert(result_output.begin(),'-');
140 
141     return result_output;
142 
143 }
144 
145 int main()
146 {
147     string num1,num2;
148     while(cin>>num1>>num2)
149     {
150         if(IsVaild(num1,num2))
151             cout<<greatNumberMulti(num1,num2)<<endl;
152         else
153             cout<<"输入数据不合法"<<endl;
154     }
155     return 0;
156 }

 

同类文章:

【模板小程序】十进制大数相加(正整数版本+整数版本【正负0】),包含合法性检查:http://www.cnblogs.com/xiaoxi666/p/7258312.html

【模板小程序】十进制大数除法(不含小数):http://www.cnblogs.com/xiaoxi666/p/7275353.html

转载于:https://www.cnblogs.com/xiaoxi666/p/7272255.html

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

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

相关文章

mysql更新字符串中某个字符串_mysql更新某个字符串字段的部分内容

如果现在需要Mysql更新字段重部分数据&#xff0c;而不是全部数据&#xff0c;应该采用何种方法呢&#xff1f;下面介绍了两种情况下Mysql更新字段中部分数据的方法&#xff0c;供您参考。Mysql更新字段中部分数据第一种情况&#xff1a;update tab set A concat(substr…

前端学习---html基础知识

HTML基本知识 学习html首先我们先看看HTML本质&#xff1a; web框架本质 我们在学socket&#xff0c;我们创建一个socketserver&#xff0c;然后运行起来&#xff0c;有一个client客户端要连接socket服务端&#xff0c;连接上之后&#xff0c;如果两边都没有close&#xff0…

Java 8最新消息

Java 8的开发再次开始主导新闻。 最近的帖子涵盖了扩展JDK 8的Milestone 7以确保其功能完整&#xff0c;Java 8中现在可用的Date / Time API以及对Java教程的更新以涵盖一些Java 8功能。 扩展JDK 8 M7 马克雷因霍尔德 &#xff08; Mark Reinhold &#xff09;以JDK 8 M6的身份…

插入排序-Java

1.算法描述 假定n是数组的长度&#xff0c; 首先假设第一个元素被放置在正确的位置上&#xff0c;这样仅需从1-n-1范围内对剩余元素进行排序。对于每次遍历&#xff0c;从0-i-1范围内的元素已经被排好序&#xff0c; 每次遍历的任务是&#xff1a;通过扫描前面已排序的子列表&a…

更改mysql数据库存放位置_更改mysql数据库存放位置

由于要做一个数据库的测试,所以选了台虚拟机进行,无奈硬盘分的太小,数据太大. 只能把数据放到新的硬盘上.所以要更改数据库的存储位置.1.新添加块硬盘,分区,挂载到/mysql下,新建lib文件夹.1.1 copy数据库文件, cp -Rp /var/lib/* /mysql/lib/1.2 修改lib权限为mysql. sudo cho…

前端:css

一,css介绍 CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;它就会按照这个样式表来对文档进行格式化&#xff08;渲染&#xff09;。 二,CSS语法 1,每个CSS样式由两个组成部分&#xff1a;选择器…

爬虫框架:scrapy

阅读目录 一 背景知识二 同步、异步、回调机制三 高性能一 背景知识 爬虫的本质就是一个socket客户端与服务端的通信过程&#xff0c;如果我们有多个url待爬取&#xff0c;采用串行的方式执行&#xff0c;只能等待爬取一个结束后才能继续下一个&#xff0c;效率会非常低。 需要…

为Openshift + MongoDb应用程序编写验收测试

验收测试用于确定是否满足规范要求。 它应该在与生产环境尽可能相似的环境中运行。 因此&#xff0c;如果您的应用程序已部署到Openshift中&#xff0c;则您将需要一个与生产环境中使用的帐户平行的帐户&#xff0c;以运行测试。 在这篇文章中&#xff0c;我们将为部署到Opensh…

《大道至简》第四章读后感

流于形式的沟通 此章主要概括沟通的方式和方法决定着我们的成败&#xff0c;在软件开发的过程中必然存在着沟通交流&#xff0c;有效的沟通可以达到事半功倍的效果。 在项目开发时&#xff0c;我们肯定需要面对客户&#xff0c;客户的需求就是我们的工作方向&#xff0c;然而我…

CSS 自适应布局

前言 本篇文章将介页面布局中的自适应布局&#xff0c;常见的自适应布局有以下2种&#xff1a;左列固定右列自适应、左右两列固定中间自适应。 1. 左列固定右列自适应布局方案 说明&#xff1a;左列固定右列自适应&#xff0c;也可以为右列固定左列自适应&#xff0c;常见于中…

mysql的表导出er关系图_使用Navicat生成ER关系图并导出的方法

平时管理数据库一般都是用cmd命令提示符&#xff0c;或是IDEA Intellij自带的Data source&#xff0c;使用Navicat比较少。这段时间&#xff0c;由于要对前后端交互的数据结构进行设计&#xff0c;直接写文档联系多表时有些困难&#xff0c;想着如果有关系图就直观很多。想到Na…

pycaffe简明文档

pycaffe简明文档 by ChrisZZ, imzhuofoxmail.com 2018年01月18日19:00:56 说明 caffe的python接口没有官方说明文档&#xff0c;例如查看一个函数的用法&#xff0c;pytorch能查到所有的用法&#xff0c;而pycaffe则需要自行去查看源码。于是手动写了一个很粗糙的文档&#xff…

Java死锁示例–如何分析死锁情况

死锁是两个或多个线程永远被阻塞的编程情况&#xff0c;这种情况发生在至少两个线程和两个或更多资源的情况下。 在这里&#xff0c;我编写了一个简单的程序&#xff0c;该程序将导致死锁情况&#xff0c;然后我们将看到如何对其进行分析。 Java死锁示例 package com.journald…

项目

不解的问题&#xff1a;表格里td能否用margin&#xff1f;覆盖z-index需要设置背景才能覆盖&#xff1f;表格与表格能否用float&#xff1f; 转载于:https://www.cnblogs.com/ssx5310518/p/7282199.html

Scude导入MySQL_FM2017_FMF赛季更新和真实修正数据库[更新至9.9,超过89000个更新]

FM2017_FMF赛季更新和真实修正数据库[更新至9.9&#xff0c;超过89000个更新]FM2017_FMF赛季更新和真实修正数据库[更新至9.9&#xff0c;超过89000个更新](2)这是国外玩家制作的一款FM2017_FMF冬季更新和真实修正数据库&#xff0c;更新至9月9日&#xff0c;超过89000个更新内…

音视频和表单的详情

网页中的音视频 <audio> 和 <vedio> 标签属性&#xff1a;autoplay 自动播放 controls 控制播放 loop 循环播放 表单 HTML 表单用于收集用户输入。 标签<form> 标签属性 action 数据的路径 enctype 传输文件 enctype"multipart/form-data" method …

使用Jackson和Super类型令牌进行Json反序列化

Datatables是一个jquery插件&#xff0c;用于显示表格信息–它可以增强简单的表或可以使用基于AJAX的数据并以表格形式显示信息。 数据表要​​求来自服务器的数据遵循特定的JSON格式才能在屏幕上显示。 考虑要显示成员实体列表的情况&#xff0c;那么对于成员而言&#xff0c…

马拉车

O(n)求字符串中的最长回文串的长度 1 char s[SIZE];2 int len[SIZE*2];3 char str[SIZE*2];4 int manacher(){//预处理字符串&#xff0c;将字符串隔开,且开头和结尾字符串要不同,防止越界&#xff0c;如aaa预处理为#a#a#a$5 int l strlen(s);6 int ls 0;7 st…

mysql otter 数据同步_MySQL数据同步之otter

一、otter介绍基于日志数据&#xff0c;用于MySQL或者ORACLE之间准实时同步数据。用途&#xff1a;mysql/oracle互相同步中间表/行记录同步二、原理及架构图otter整体模块manager (提供web页面进行同步管理)arbitrate (分布式调度&#xff0c;可跨IDC机房)node (同步过程setl)c…

ubuntu中获取文件名称并生成txt文件

简介&#xff1a; 在机器视觉学习过程中&#xff0c;通常会经常批量处理一些图片&#xff0c;在&#xff35;&#xff42;&#xff55;&#xff4e;&#xff54;&#xff55;下可以使用find命令&#xff0c;来实现将文件名全部读取出来&#xff0c;生成列表txt文件&#xff0c;…