20. 计算器PLUS
1 问题描述
高老师的学术科研开展的如火如荼,但最近有件事让他很烦恼,在做学术研究过程中,经常需要对很大很大的数据进行计算,而现有的计算器没办法满足这种计算需求,所以现在想请大家帮忙实现一个计算器PLUS版。
为了减少大家的工作量,高老师已经将函数的输入输出接口定义完成,你只需编写计算器PLUS的核心部分。
例如 plus() , minus() 和 multiply() 函数,有三个char * 类型的参数 a、b 和 c,a 和 b 分别是参与运算的两个整数,c 用来存放运算结果。所有数字以字符串的形式保存。你的计算结果(在 c 中保存)中不应包含任何前导零。
* 注意,你只需提交编写的三个函数即可。
所有的测试点中的整数,包括结果整数的十进制位数均不超过 1000,均保证其包含的所有整数非负。但不保证结果非负。
输入的数字可能存在前导0
预设代码
前置代码
/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */#include <stdio.h>
#include <string.h>void plus(const char * a, const char * b, char * c);
void minus(const char * a, const char * b, char * c);
void multiply(const char * a, const char * b, char * c);int main()
{static char a[100005];static char b[100005];static char c[200005];static char s[2];while (scanf("%s %s %s", a, s, b) == 3) {if (s[0] == '+') {plus(a, b, c);} else if (s[0] == '-') {minus(a, b, c);} else if (s[0] == '*') {multiply(a, b, c);}printf("%s\n", c);}return 0;
}/* PRESET CODE END - NEVER TOUCH CODE ABOVE */
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 |
以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
2 解题
<1>第一次尝试
刚开始没有意识到这个题的考点,还以为是要复习一下C语言的知识点,字符串和整型数字的转换,于是我开始了
代码就不放了,总之就是算是偷懒的做法
代码主要是在提取,提取出来以后直接相乘得到结果,然后再把结果存进去
不过也借这个机会复习了一下怎么转换字符串和int整型这两种类型了,整理了一下,记录在这了
https://blog.csdn.net/qq_41680771/article/details/121058779
<2> 最终AC版
其实算法很简单(没有算法好像),主要就是不断调试来修改代码符合题意
题目中说位数不超过1000,我们平时说的一亿才11位,所以提取出来进行运算的操作肯定是不行的了
输入可能会有前缀0,注意进行处理避免没必要的运算,另外输出是不需要前缀的
加法:每一位取出来相加,对应的结果报存在整型数组tmp[]里面,注意是从后往前存的,然后遍历一遍,根据10进制特点和规律进行调整,相加的话可能会使得位数增加
减法:结果的正负处理方式不一样,分开处理,最后的结果如果是负数的话,需要在c里面加上“-”号
乘法:我是对于b的每一位,用a的每一位去乘它,对应结果保存在tmp的相应位置
好吧,其实就是竖式运算~~~
得到的结果累加,最后再处理
代码
#include <stdio.h>
#include <string.h> void plus(const char * a, const char * b, char * c);
void minus(const char * a, const char * b, char * c);
void multiply(const char * a, const char * b, char * c); int main()
{ static char a[100005]; static char b[100005]; static char c[200005]; static char s[2]; //freopen("file out.txt","r",stdin); while (scanf("%s %s %s", a, s, b) == 3) { if (s[0] == '+') { plus(a, b, c); } else if (s[0] == '-') { minus(a, b, c); } else if (s[0] == '*') { multiply(a, b, c); } printf("%s\n", c); } return 0;
} void plus(const char * a, const char * b, char * c){int lena,lenb,lentmp;int notzeroA,notzeroB;int tmp[20005];int i=0;int flag=0;lena = strlen(a);lenb=strlen(b);while(a[i]=='0') //处理前缀0i++;notzeroA=i; //第一个不是0的位置i=0;while(b[i]=='0')i++;notzeroB=i;// for(i=0;(lena--)>0||(lenb--)>0;i++){ //这个会导致后面一个语句不运行,||类型,前面已经是真的了for(i=0;lena>notzeroA||lenb>notzeroB;i++){lena--; lenb--;if(lena<notzeroA){ //a完了tmp[i]=b[lenb]-'0';}else if(lenb<notzeroB){ //b完了tmp[i]=a[lena]-'0';}elsetmp[i]=(a[lena]-'0')+(b[lenb]-'0'); }lentmp=i;for(i=0;i<lentmp;i++){if(flag){tmp[i]+=1;flag=0;}if(tmp[i]>9){flag=1; //需要进1的标志tmp[i]%=10;} }if(flag) //总和大于当前位数,需要增加tmp[lentmp++]=1;while(tmp[lentmp-1]==0)lentmp--; for(i=0;i<lentmp;i++){c[i]=tmp[lentmp-i-1]+'0';}c[i]='\0'; //记得增加结束符}
void minus(const char * a, const char * b, char * c){int lena,lenb,lentmp;int tmp[20005];int i=0;int flag=0;int positiveflag=0;lena = strlen(a);lenb=strlen(b);for(i=0;lena>0||lenb>0;i++){lena--; lenb--;if(lena<0){tmp[i]=0-(b[lenb]-'0');}else if(lenb<0){tmp[i]=a[lena]-'0';}elsetmp[i]=(a[lena]-'0')-(b[lenb]-'0'); }lentmp=i;while(i--){ //只要第一个不为0的数大于0,那么结果就是正数,注意tmp的逆序存储if(tmp[i]!=0){if(tmp[i]>0){positiveflag=1;break;}else if(tmp[i]<0){break;} }}if(positiveflag){ //正数处理for(i=0;i<lentmp;i++){if(flag){tmp[i]-=1;if(tmp[i]<0){tmp[i]+=10;}elseflag=0;}else{if(tmp[i]<0){tmp[i]+=10;flag=1;}}}flag=0;}else{for(i=0;i<lentmp;i++){if(flag){ tmp[i]+=1;if(tmp[i]>0){tmp[i]=tmp[i]*(-1)+10;}else if(tmp[i]<0){tmp[i]*=(-1);flag=0;}else{flag=0;} }else{if(tmp[i]>0){tmp[i]=tmp[i]*(-1)+10;flag=1;}if(tmp[i]<=0){tmp[i]*=(-1); } } }} i=lentmp; //处理前缀0,输出不需要前缀while(i--){if(tmp[i])break;}lentmp=++i;if(positiveflag){for(i=0;lentmp--;i++){ c[i]=tmp[lentmp]+'0';}}else{if(tmp[lentmp-1]!=0){ //负数需要添加-号c[0]='-';for(i=1;lentmp--;i++){ c[i]=tmp[lentmp]+'0';}}else{i=0;c[i++]='0';}}c[i]='\0';
}void multiply(const char * a, const char * b, char * c){int lena,lenb,lentmp;int notzeroA,notzeroB;int tmp[20005]={0};int i=0,j=0,k=0;int flag=0;lena=strlen(a);lenb=strlen(b);while(a[i]=='0')i++;notzeroA = i;while(b[j]=='0')j++;notzeroB = j;if(!lena||!lenb||i==lena||j==lenb){ //如果有是0的项,那么完全没必要再操作了c[0]='0';c[1]='\0';return;}i=lenb;while(--i>=notzeroB){j=lenb-i-1; //tmp下标每次的开始是在增加的k=lena;if(b[i]=='0')continue;while(--k>=notzeroA){tmp[j++]+=(a[k]-'0')*(b[i]-'0');}}for(i=0;i<j;i++){if(flag){tmp[i]+=flag;flag=0;if(tmp[i]>9){while(tmp[i]>9){flag++;tmp[i]-=10;}}elseflag=0;}else{while(tmp[i]>9){flag++;tmp[i]-=10;}}}while(flag){ //tmp里面进行正确格式处理以后可能会位数增加tmp[i]+=flag;flag=0;while(tmp[i++]>9){flag++;tmp[i]-=10;}}lentmp=i;for(i=0;i<lentmp;i++){c[i]=tmp[lentmp-i-1]+'0'; }c[i]='\0';
}
3 小结
- while 或者for if这个射击条件判断的语句要注意编译器不一定会判断所有给出的条件,比如**&&**类型,如果第一个就是false的话,后面就不会判断了
for(i=0;(lena--)>0||(lenb--)>0;i++)
比如这个语句如果前面就是TRUE的话,后面len–就不会运行,容易导致程序出错
20. 计算器PLUS相关推荐
- 从零开始的iOS开发: 20 | 计算器APP
目录 一.开发环境 二.基础知识 1.往期知识点 2.简易自动布局--Stack View 三.实验步骤 1.先在Xcode建立一个APP项目 2.界面搭建 3.连接控件与代码 4.补充代码,完善功能 ...
- OC基础--OC中的类方法和对象方法
PS:个人感觉跟C#的静态方法和非静态方法有点类似,仅仅是有点类似.明杰老师说过不要总跟之前学过的语言做比较,但是个人觉得,比较一下可以加深印象吧.重点是自己真的能够区分开! 一.OC中的对象方法 1 ...
- Kettle基本操作
1.简介 ETL(EXTRACT-Transform-Load的缩写,即数据抽取,转换,装载的过程),对于企业或行业的应用来说数据的处理,转换,迁移必不可少,所以需要我们掌握,这里的ETL工具是Ket ...
- 计算机vb实验报告,2016年华北科技学院计算机学院综合性实验实验报告(VB).doc
文档介绍: 华北科技学院计算机学院综合性实验 实验报告 课程名称程序设计语言(VB) 实验学期 2015 至 2016 学年第 2 学期 学生所在系部 XXXX学院 年级 2015级专业班级 XXB1 ...
- py 工gong师 完整版
01-基础篇 06 基础篇-01 计算机结构01.avi 05 基础篇-01 电脑简史02.avi 04 基础篇-01 电脑简史01.avi ...
- 利用php屏蔽海外ip访问,高效实现
<?php/*** 屏蔽海外ip访问* 使用ip2long函数得到ip转为整数的值,判断值是否在任一一个区间中* 以下是所有国内ip段* 调用方法:IschinaIp($ALLIPS)* 返回值 ...
- 06-1. 简单计算器(20)
06-1. 简单计算器(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 张彤彧(浙江大学) 模拟简单运算器的工作.假设计算器只 ...
- 习题2.1 简单计算器 (20 分)
习题2.1 简单计算器 (20 分) 模拟简单运算器的工作.假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算. 输入格式: 输入在一行中给出一个四则运 ...
- deepin系统15.6版本安装执行那个exe文件_深度操作系统 deepin 20(1003)正式版发布:计算器支持科学计算,新增邮件、相机等应用...
原标题:深度操作系统 deepin 20(1003)正式版发布:计算器支持科学计算,新增邮件.相机等应用 IT之家10月22日消息 deepin 20 正式版发布一个月后,社区版本迎来了第一次更新 ( ...
最新文章
- linux mysql 开启远程访问
- 阿里云Maven镜像配置
- 信息学奥赛一本通(1037:计算2的幂)
- 移动站原生的select实现省市区联动选择
- oracle 自治事物,自治事务 - 努力创造未来! - BlogJava
- 时间序列分析工具箱——tibbletime
- 关于华为路由器下一跳的心得
- softmgr主程序_360软件管家下载的安装程序在哪个文件夹
- jQuery第六章课后作业
- 电子通信协议之CAN总线协议篇
- 名人论数学——数学的本质
- 被国人误解了千年的七句话
- 【全国计算机等级考试二级教程——C语言程序设计(2021年版)编程题答案-第7章】
- iPhone3G、N96、N95、i908E对比
- 小米4s真机测试运行失败
- 编码分布式矩阵乘法(Coded Distributed Matrix Multiplication, CDMM)问题简单介绍
- 通过数据可视化进行足球进球方式分析球员属性
- CIKM'2017 最佳论文鉴赏
- asp通用数据库连接类 access mssql mysql_asp.net 连接mssql mysql access Excel 2007数据库
- 靶向抗体偶联-靶向EGFR抗体偶联药物技术-瑞禧