【51Nod】1005 大数加法
给出2个大整数A,B,计算A+B的结果。
Input
第1行:大数A 第2行:大数B (A,B的长度 <= 10000 需注意:A B有可能为负数)
Output
输出A + B
Input示例
68932147586 468711654886
Output示例
537643802472
====================================================================================================
问题解法分析:
因为长度小于10000 所以可以依据模拟进位的方法进行解决
解决思路如下:
1:比较两个字符串类型:
如果为如果同为正数(负数) 则进行直接相加(负数相加负号)
若为一正一负,则对负数取消负号进行正数与负数的相减
保证此时字符串已经不存在正负号问题
2:对字符串进行转换
比较两个字符串的长度,若长短不一样则对短的字符串进行补齐 保证两个字符串长短一样
转换函数如下:
void Trans(char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2)
{
int len_num1=;
int len_num2=;
int i=;
while(str_num1[i]!='\0')
{
len_num1++;
i++;
}
// printf("字符串1的长度: length1=%d\n",len_num1);
i=;
while(str_num2[i]!='\0')
{
len_num2++;
i++;
}
// printf("字符串2的长度: length2=%d\n\n",len_num2); tempbuf1[]='';
tempbuf2[]=''; //=======================================================================
if(len_num2>=len_num1) //补成相同长度
{
for(i=;i<=(len_num2-len_num1);i++)
{
tempbuf1[i]='';
}
for(i=len_num2-len_num1+;i<=len_num2;i++)
{
tempbuf1[i]=str_num1[i-(len_num2-len_num1+)];
}
for(i=;i<=len_num2;i++)
{
tempbuf2[i]=str_num2[i-];
}
}
//------------------------------------------
else if(len_num2<len_num1)
{
for(i=;i<=(len_num1-len_num2);i++)
{
tempbuf2[i]='';
}
for(i=len_num1-len_num2+;i<=len_num1;i++)
{
tempbuf2[i]=str_num2[i-(len_num1-len_num2+)];
}
for(i=;i<=len_num1;i++)
{
tempbuf1[i]=str_num1[i-];
}
} }
3:进行加减运算
对已经处理过的字符串进行加减计算
计算方式模仿竖式进位进行计算
加法算法:
int i=;
int temp=;
int jinwei=;
int len=;
while(tempbuf1[i]!='\0')
{
len++;
i++;
}
for(i=len-;i>=;i--)
{
temp=(int)(tempbuf1[i]+tempbuf2[i]+jinwei-);
if(temp>=)
{
temp=temp-;
jinwei=;
}
else jinwei=;
result[i]=(char)(temp+);
}
减法算法:
int i=;
int temp=;
int jiewei=;
int len=;
int ret=; while(tempbuf1[i]!='\0') // tempbuf1 和 tempbuf2 的长度相等
{
len++;
i++;
} ret = Compare(tempbuf1,tempbuf2);
if(ret==)
{
for(i=len-;i>=;i--)
{
temp = (int)tempbuf1[i] - (int)tempbuf2[i] - jiewei;
if (temp>=)
{
result[i]=(char)(temp+);
jiewei=;
}
else if (temp<)
{
result[i]=(char)(temp++);
jiewei=;
}
}
ThrowAway_0 (result);
}
else if(ret==)
{
memset(result,,);
result[]='';
}
else if(ret==-)
{
for(i=len-;i>=;i--)
{
temp = (int)tempbuf2[i] - (int)tempbuf1[i] - jiewei;
if (temp>=)
{
result[i]=(char)(temp+);
jiewei=;
}
else if (temp<)
{
result[i]=(char)(temp++);
jiewei=;
}
}
ThrowAway_0 (result);
memset(buf1,,);
sprintf(buf1,"-%s",result);
strcpy(result,buf1);
}
在对减法进行运算时,存在大数减小数的问题,因此需要对字符串长度进行比较:
比较函数如下:
int Compare(char *tempbuf1,char *tempbuf2)
{
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
char buf1[]={};
char buf2[]={};
Trans(tempbuf1,tempbuf2,buf1,buf2);
memset(tempbuf1,,);
memset(tempbuf2,,);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2); int ret=;
int count=;
while(count<)
{ int m=(int)tempbuf1[count]-;
int n=(int)tempbuf2[count]-;
if(m==n)
{
count++;
ret=;
}
else if(m>n)
{
// printf("tempbuf1>tempbuf2\n");
ret=;
break; }
else if(m<n)
{
// printf("tempbuf1<tempbuf2\n");
ret=-;
break;
}
}
return ret;
}
4:对多余项进行缩减:
将剩余0去掉
void ThrowAway_0 (char *tempbuf ) // 去除结果前面的 连续的无意义的 "0"
{
char buf[]={}; int n = strlen(tempbuf)-;
int i=;
while(i<n)
{
if (tempbuf[i]!='')
{
break;
}
else
{
i++;
}
}
int Throw = i;
for (i=;i<=n-Throw;i++)
{
buf[i]=tempbuf[i+Throw];
} strcpy(tempbuf,buf); }
5:对结果进行输出 完成。
测试代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h> void Add (char *tempbuf1, char *tempbuf2, char *result); // 大数相加 result = tempbuf1 + tempbuf2 void Sub(char *tempbuf1, char *tempbuf2, char *result); // 大数相减 result = tempbuf1 - tempbuf2 (默认前者大) void Trans (char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2); // 大数转化为等长,且最前面添加 “0” int Compare(char *tempbuf1,char *tempbuf2);//比较两个字符串的长度 相同返回0 buf1长返回1 buf2长返回-1 void ThrowAway_0 (char *tempbuf ); // 去除结果前面的 连续的无意义的 "0" int main()
{ char str1[100001];
char str2[100001];
char result[100001]={0};
short result_flag = 0; scanf("%s %s",str1,str2); if(str1[0] == '-' && str2[0] == '-')
{
str2[0] = str1[0] = '0';
Add(str1,str2,result);
if(result[0]!= '0')
{
printf("-");
printf("%s\n",result);
} else
printf("0\n");
}
else if(str1[0] == '-' && str2[0] != '-')
{
str1[0] ='0'; Sub(str2,str1,result);
printf("%s\n",result);
}
else if(str1[0] != '-' && str2[0] == '-')
{
str2[0] = '0';
Sub(str1,str2,result);
printf("%s\n",result);
}
else
{
Add(str1,str2,result);
printf("%s\n",result);
} return 0;
} void Trans(char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2)
{
int len_num1=0;
int len_num2=0;
int i=0;
while(str_num1[i]!='\0')
{
len_num1++;
i++;
}
i=0;
while(str_num2[i]!='\0')
{
len_num2++;
i++;
} tempbuf1[0]='0';
tempbuf2[0]='0'; //=======================================================================
if(len_num2>=len_num1) //补成相同长度
{
for(i=1;i<=(len_num2-len_num1);i++)
{
tempbuf1[i]='0';
}
for(i=len_num2-len_num1+1;i<=len_num2;i++)
{
tempbuf1[i]=str_num1[i-(len_num2-len_num1+1)];
}
for(i=1;i<=len_num2;i++)
{
tempbuf2[i]=str_num2[i-1];
}
}
//------------------------------------------
else if(len_num2<len_num1)
{
for(i=1;i<=(len_num1-len_num2);i++)
{
tempbuf2[i]='0';
}
for(i=len_num1-len_num2+1;i<=len_num1;i++)
{
tempbuf2[i]=str_num2[i-(len_num1-len_num2+1)];
}
for(i=1;i<=len_num1;i++)
{
tempbuf1[i]=str_num1[i-1];
}
} } void Add(char *tempbuf1, char *tempbuf2, char *result) // 大数相加 result = tempbuf1 + tempbuf2
{
char buf1[100001]={0};
char buf2[100001]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2); int i=0;
int temp=0;
int jinwei=0;
int len=0;
while(tempbuf1[i]!='\0')
{
len++;
i++;
}
for(i=len-1;i>=0;i--)
{
temp=(int)(tempbuf1[i]+tempbuf2[i]+jinwei-96);
if(temp>=10)
{
temp=temp-10;
jinwei=1;
}
else jinwei=0;
result[i]=(char)(temp+48);
}
ThrowAway_0 (result); } //================================================ void ThrowAway_0 (char *tempbuf ) // 去除结果前面的 连续的无意义的 "0"
{
char buf[100000]={0}; int n = strlen(tempbuf)-1;
int i=0;
while(i<n)
{
if (tempbuf[i]!='0')
{
break;
}
else
{
i++;
}
}
int Throw = i;
for (i=0;i<=n-Throw;i++)
{
buf[i]=tempbuf[i+Throw];
} strcpy(tempbuf,buf); } //======================================================= //extern "C" __declspec(dllexport)
void Sub(char *tempbuf1, char *tempbuf2, char *result) // 大数相减 result = tempbuf1 - tempbuf2
{
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
memset(result,0,200);
char buf1[100001]={0};
char buf2[100001]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
memset(tempbuf1,0,100001);
memset(tempbuf2,0,100001); strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2); int i=0;
int temp=0;
int jiewei=0;
int len=0;
int ret=1; while(tempbuf1[i]!='\0') // tempbuf1 和 tempbuf2 的长度相等
{
len++;
i++;
} ret = Compare(tempbuf1,tempbuf2);
if(ret==1)
{
for(i=len-1;i>=0;i--)
{
temp = (int)tempbuf1[i] - (int)tempbuf2[i] - jiewei;
if (temp>=0)
{
result[i]=(char)(temp+48);
jiewei=0;
}
else if (temp<0)
{
result[i]=(char)(temp+10+48);
jiewei=1;
}
}
ThrowAway_0 (result);
}
else if(ret==0)
{
memset(result,0,100001);
result[0]='0';
}
else if(ret==-1)
{
for(i=len-1;i>=0;i--)
{
temp = (int)tempbuf2[i] - (int)tempbuf1[i] - jiewei;
if (temp>=0)
{
result[i]=(char)(temp+48);
jiewei=0;
}
else if (temp<0)
{
result[i]=(char)(temp+10+48);
jiewei=1;
}
}
ThrowAway_0 (result);
memset(buf1,0,100001);
sprintf(buf1,"-%s",result);
strcpy(result,buf1);
} } //====================================================================== //=================================================================================== int Compare(char *tempbuf1,char *tempbuf2)
{
ThrowAway_0 (tempbuf1);
ThrowAway_0 (tempbuf2);
char buf1[100001]={0};
char buf2[100001]={0};
Trans(tempbuf1,tempbuf2,buf1,buf2);
memset(tempbuf1,0,100001);
memset(tempbuf2,0,100001);
strcpy(tempbuf1,buf1);
strcpy(tempbuf2,buf2); int ret=1;
int count=0;
while(count<100001)
{ int m=(int)tempbuf1[count]-48;
int n=(int)tempbuf2[count]-48;
if(m==n)
{
count++;
ret=0;
}
else if(m>n)
{
// printf("tempbuf1>tempbuf2\n");
ret=1;
break; }
else if(m<n)
{
// printf("tempbuf1<tempbuf2\n");
ret=-1;
break;
}
}
return ret;
}
此外,对于大数运算不限于加减运算 更多运算方法可以参考大数模板:
参考内容:
【51Nod】1005 大数加法的更多相关文章
- 大数高精度加减乘除 51nod 1005 大数加法
1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大数B ...
- 51nod 1005 大数加法
#include<iostream> #include<string> using namespace std; #define MAXN 10001 },b[MAXN]={} ...
- 51 Nod 1005 大数加法【Java大数乱搞,python大数乱搞】
1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大数B (A,B的长度 ...
- 51nod 1005 1027 1029 高精度
Java大数用法参考:https://www.cnblogs.com/jin-nuo/p/5313205.html 1005 大数加法: import java.util.*; import java ...
- 51NOD 1005
1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大 ...
- 51NOD 大数加法以及python写法
练练 大数加法一般为小学生式的"竖式计算"要特别注意的是借位与进位的问题(先给看c++写法,我怕先看了python写法,会看不下去c++写法)这题还有要注意的是 1.同符号的话,直 ...
- c#大数加法
在C#中,我们经常需要表示整数.但是,c#的基本数据类型中,最大的long也只能表示-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807之间的数 ...
- 玲珑杯1007-A 八进制大数加法(实现逻辑陷阱与题目套路)
题目连接:http://www.ifrog.cc/acm/problem/1056 DESCRIPTION Two octal number integers a, b are given, and ...
- 51nod 1027大数乘法
题目链接:51nod 1027大数乘法 直接模板了. #include<cstdio> #include<cstring> using namespace std; ; ; ; ...
随机推荐
- 使用Visual Studio 2010 - 初学者系列 - 学习者系列文章
本文介绍Visual Studio 2010的基本使用. 1. 欢迎界面 2. 进入界面 3.选择菜单中的项目 4.选择项目路径,还有空白解决方案 5.选择 新建解决方案文件夹 6.选择新建项目 ...
- android微信付费
原文地址:http://blog.csdn.net/intbird 微信官方文档地址:t=resource/res_main_tmpl&verify=1&lang=zh_CN" ...
- TableLayout中怎么填充相同的布局
在Android界面xml文件中可以导入另一个xml文件,就能实现一个功能就是重复利用相同的xml布局 有两种方法进行处理: include引入 定义一个布局Tab_flag.xml <?xml ...
- JavaScript闭包小窥
众所周知,JavaScript没有块级作用域,只有函数作用域.那就意味着定义在函数中的参数和变量在函数外部是不可见的,而在一个函数内部任何位置定义的变量,在该函数内部任何地方都可见.这带来的好处是内部 ...
- POI操作EXCEL之导出Excel(设置有效性,下拉列表引用)
本人使用的是poi-bin-3.10-FINAL-20140208.zip 版本的poi以下是程序关键代码: //需要引用的类 import java.io.File; import java.io. ...
- windows 8以上找回开始菜单
步骤如下: 右击任务栏,选择工具栏——新建工具 在工具栏---新建工具栏的输入框中输入,”C:\ProgramData\Microsoft\Windows\Start Menu\Programs,然后 ...
- RikMigrations 或 Migrator.NET 进行自动化的数据库升级
一种版本化的数据库脚本管理机制 现今开发的软件当中,多数系统的数据都是基于数据库存储的,但是由于软件变化的复杂性,相对于维护代码,数据库架构的版本并不是那么好维护. 这里本人针对实际情况,理想化出一种 ...
- 【学习笔记】锋利的jQuery(三)事件和动画
一.jQuery事件 1,加载事件 $(document).ready(function(){...}) //等同于$(function(){..}) $(window).load(function( ...
- Binder机制,从Java到C (9. IPC通信过程)
1.一次IPC通信過程的幾個步驟 一次通信过程简单的说有下面5个步骤,第一眼看上去,肯定不知道什么玩意,多看几遍,慢慢看,其实是能理解的. 1. Client将数据封装成Parcel. (前面已经讲过 ...
- C/C++ 中 const 修饰符用法总结
C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...