四则运算之加减法

问题描述

计算机所能完成的一个基本功能就是完成数据的计算,譬如加法、减法等等。但是在任何一种计算机上,计算中能够使用的数字都是有一定范围的,超过了范围,就没法得到精确的结果。

你现在接受了一个任务,要编写一个高精度计算器的核心部分。所谓高精度计算器,就是可以计算很大很大的数据的计算器。而你所需要编写的程序,就是真正完成高精度加法和高精度减法运算的两个函数,因为程序其它的部分已经由别人编写好了。

函数的输入、输出接口也已经定义完成,譬如 plus() 函数,它有三个参数 a、b 和 c,都是 char * 类型。a 和 b 分别是参加运算的两个整数,而 c 用来存放运算的结果。所有的数字都是以字符串的形式保存的。

注意,只需提交你自己编写的两个函数。

输入

输入的每一行是两个十进制的正整数和一个运算符,每个整数可以由最多 500 个数字组成。运算符可以是加号或者减号。

输出

对应着输入的每一行数据,输出计算的结果,每个结果占一行。

预设代码

前置代码

view
plain
print?

  1. /* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */
  2. #include <stdio.h>
  3. #include <string.h>
  4. void plus(char *a, char *b, char *c);
  5. void minus(char *a, char *b, char *c);
  6. int main()
  7. {
  8. char a[1000];
  9. char b[1000];
  10. char c[1000];
  11. char s[2];
  12. while (scanf("%s %s %s\n", a, s, b) == 3) {
  13. if (s[0] == ‘+‘) {
  14. plus(a, b, c);
  15. } else if (s[0] == ‘-‘) {
  16. minus(a, b, c);
  17. }
  18. printf("%s\n", c);
  19. }
  20. return 0;
  21. }
  22. /* PRESET CODE END - NEVER TOUCH CODE ABOVE */
测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 以文本方式显示

  1. 1 + 2?
  2. 3 - 2?

以文本方式显示

  1. 3?
  2. 1?

1秒 64M 0

题解思路

大致思路:

我用的思路是,先将a,b两个字符串倒序转化为整形数组,然后模拟加减法的竖式计算通过数组之间的“进位”来将最后的结果存入一个整形数组里面,最后再把这个整形数组转化为字符型的数组。

具体实现方式以及需要注意的事项:

首先预制的函数里面在输入中多了“/n”,这个我们在自己编写的时候可以先将其去掉,要不然读入的时候会有问题。

然后就是进行字符串的转化,需要注意的是需要先把字符串前面的前导0去掉,借用大神的方法while(a[0]==‘0‘)a++;while(b[0]==‘0‘)b++;这样就可以吧字符串前面的前导0去掉。但是应该注意字符串a=“0000”或b=“00000”的这种情况,这种情况下会导致,把字符串清空,这里需要判断一下,如果经过上面的处理之后字符串的长度为0,我们就可以人为的令字符串的长度为1,a[0]=0,b[0]=0.然后进行转化,转化的时候一般有两种方法比较容易想到一是在后面-‘0’,另一种是在后面-48,不过看发帖说‘0’-‘0’=‘\0’(自己理解是因为两个字符是一样的,所以减完之后就是空了),所以还是用第二种方法进行倒序的转换。这里对于减法需要注意,为了是最后的‘-’比较好处理,所以我们要用大数减去小数,在做转换的时候,如果a<b,那么就需要做相应的处理可以再转化数组的时候将大的数组放进规定的放大数的数组里,并做好标记;也可以直接转化,然后在减的时候用表示大数的数组减去表示小数的数组,并做标记)。注意在每次调用函数的时候都要将自己定义的三个整形数组清0.

然后就是计算了,对于加法,按照竖式计算的顺序每一位的两个数相加,相加的结果存入c[i]里面,如果c[i]>9,则c[i+1]++;c[i]+=10;这样循环着计算(循环的长度是两个数组里面最长的数组的长度),最后计算完了之后要判断c[length](length表示两个数组里面最长的数组的长度)是否等于1,即判断最高位是否有进位,如果有那么length++。对于减法,思路和加法一样,按照竖式计算的顺序每一位的两个数相减,相减的结果存入c[i]里面,如果如果c[i]<0,则c[i+1]
- -;c[i]+=10;这样循环着计算(循环的长度是两个数组里面最长的数组的长度),最后计算完了之后要判断数组a的前面(length表示两个数组里面最长的数组的长度)是否有等于0的位,即判断前面的位是否被借走,剩下0,如果是那么length--,终止的条件是c[length--]!=0(就是所说的退位)。

最后就是将整形数组c中的数字转换为字符串,即每个位上的数+48.要注意减法中如果最后的结果是负数的时候要在数组的前面加‘-’,因为最后是‘%s’输出的,所以可以领cc[0]=’-’.还要注意在转换完成的时候要在字符数组的最后加上‘\0’,这样可以防止由于数组没有初始化而导致输出乱码。

实现代码

<span style="font-family:Microsoft YaHei;font-size:14px;">void plus(char *a, char *b, char *c)
{
	int lengtha,lengthb,length;
	int i,j;
	int aa[505],bb[505],cc[505];
    for(i=0;i<505;i++)
    {
    	aa[i]=0;
    	bb[i]=0;
    	cc[i]=0;
    }
	while(a[0]=='0')a++;
	while(b[0]=='0')b++;
	lengtha=strlen(a);
	lengthb=strlen(b);

	if(lengtha==0&&lengthb!=0)
	{
		length=lengthb;
		aa[0]=0;
	}
	else if(lengtha!=0&&lengthb==0)
	{
		length=lengtha;
		bb[0]=0;
	}
	else if(lengtha==0&&lengthb==0)
	{
		length=1;
		aa[0]=0;
		bb[0]=0;
	}
	else if(lengtha>lengthb)
	{
		length=lengtha;     //找出最长的数
	}
	else
	{
		length=lengthb;
	}
	for(i=0;i<lengtha;i++)
	{
		aa[i]=a[lengtha-1-i]-48;
	}
	for(i=0;i<lengthb;i++)              //转换字符串为整形数组
	{
		bb[i]=b[lengthb-1-i]-48;
	}
	for(i=0;i<length;i++)
	{
		cc[i]+=aa[i]+bb[i];
		if(cc[i]>9)                //计算
		{
			cc[i+1]++;
			cc[i]-=10;
		}
	}
	if(cc[length]>0)
	{
		length++;
	}
	for(j=0;j<length;j++)
	{
		c[j]=cc[length-1-j]+48;
	}
	c[length]='\0';
} 

void minus(char *a, char *b, char *c)
{
	int lengtha,lengthb,length;
	int i,j,temp=0,temp2;
	int aa[505],bb[505],cc[505];
	for(i=0;i<505;i++)
	{
		aa[i]=0;
		bb[i]=0;
		cc[i]=0;
	}
	temp=0;
	while(a[0]=='0')a++;
	while(b[0]=='0')b++;
	lengtha=strlen(a);
	lengthb=strlen(b);

	if(lengtha!=0&&lengthb==0)
	{
		length=lengtha;
		bb[0]=0;
	}
	else if(lengthb!=0&&lengtha==0)
	{
		length=lengthb;
		aa[0]=0;
	}
	else if(lengtha==0&&lengthb==0)
	{
		length=1;
		aa[0]=0;
		bb[0]=0;
	}
	else if(lengtha==lengthb)
	{
		length=lengtha;
		temp2=strcmp(a,b);
		if(temp2<0)
		{
			temp=2;
		}
	}
	else if(lengthb>lengtha)
	{
		length=lengthb;
		temp=1;
	}
	else
	{
		length=lengtha;
	}

	if(temp!=0)
	{
		for(i=0;i<lengthb;i++)
		{
			aa[i]=b[lengthb-1-i]-48;
		}
		for(i=0;i<lengtha;i++)
		{
			bb[i]=a[lengtha-1-i]-48;
		}
	}
	else
	{
		for(i=0;i<lengtha;i++)
		{
			aa[i]=a[lengtha-1-i]-48;
		}
		for(i=0;i<lengthb;i++)
		{
			bb[i]=b[lengthb-1-i]-48;
		}
	}

	for(j=0;j<length;j++)
	{
		cc[j]+=aa[j]-bb[j];
		if(cc[j]<0)
		{
			cc[j+1]--;
			cc[j]+=10;
		}
	}
	while(cc[length]==0&length>0)
	{
		length--;
	}
	length++;

	if(temp==0)
	{
		for(i=0;i<length;i++)
		{
			c[i]=cc[length-1-i]+48;
		}
		c[length]='\0';
	}
	else
	{
		c[0]='-';
		for(i=1;i<=length;i++)
		{
			c[i]=cc[length-i]+48;
		}
		c[length+1]='\0';
	}
}</span>

时间: 2024-11-09 07:50:44

四则运算之加减法的相关文章

关于Velocity加减法等四则运算的迷思

曾今有一个FreeMarker摆在我面前. 我没有好好珍惜, 遇到了Velocity我才想起失去的美好... 需求是把PC网页点击. 手机网页点击.App点击相加得到总点击量显示出来: $article.hits+$article.wapHits+$article.mobileHits 理想非常美好, 现实输出的是:Number+Number+Number的一个大字符串(想当年. 用FreeMarker的时候. 加减运算直接上, 而现在...) 据说须要在+号等四则运算符两側都加上空格. 好吧.

软件工程第一次作业,小学生四则运算的出题程序

一.背景 阿超有个儿子上小学二年级,老师每天让家长给孩子出30道加减法题,虽然不多,但是每天都做也算是个负担,阿超作为一个老牌程序员当然想用计算机来解决这个小问题,目前对于这个问题对于任何语言都不是问题,比如: C/C++.C#.Java.Python.VB.JavaScript.Perl…… 具体要求如下: 能自动生成小学四则运算题目(注意是给小学生用的,要是结果出现负数的话他们会迷茫的!) 除了整数外,还要支持真分数的四则运算 请大家用任何一种自己擅长的语言来编写这段程序,并把程序的介绍和自

不太完美的四则运算

拖啊拖,终于记得把它上传了! 题目 写一个能自动生成小学四则运算题目的命令行"软件",分别满足下列各种需求.下面这些需求都可以用命令行参数的形式来指定: a.)除了整数以外,还支持真分数的运算.(例如1/6+1/8=7/24). b.)让程序能接受用户输入的答案,并判断对错.最后给出总对/错的数量. c.)逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目(最多10个运算符,括号的数量不限制): 25-3*4-2/2+89=?          1/2+1/3-1/4=?

介绍一款原创的四则运算算式生成器:CalculateIt2

家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:CalculateIt2.项目是开源的,源码地址是:https://github.com/daxnet/CalculateIt2.也可以在标准的.NET Framework 4.6.1的项目中,通过nuget来引用这个类库,nuget ID是:CalculateIt2.Engine.为什么名字后面有一个"2&

第二周-四则运算更新

四则运算功能更新: HTTPS:https://git.coding.net/li_yuhuan/CalculateTest.git SSH:[email protected]:li_yuhuan/CalculateTest.git 代码: static void Main(string[] args) { int length = args.Length; if (0 == length) { for (int i = 0; i < 20; i++) { ShowTest(false); }

关于四则运算表达式生成和答案校验的笔记

软件工程的个人项目是写一个面向小学生的四则运算题目生成和校验工具.主要功能有两个,一是生成四则运算题目,二是对给定的题目和答案,校验其中答案的正确性. 时间表格 前期构思的时间比较多,但是在编码和测试中还是花费了不少的时间. 由于采用的c语言,在字符串的处理和内存管理上花费了较多的时间. PSP2.1 Personal Software Process Stages Time Planning 计划 · Estimate · 估计这个任务需要多少时间 20h Development 开发 · A

《四则运算》2

题目要求:随机产生30个的四则运算 题目避免重复: 可定制(数量/打印方式): 可以控制下列参数: 是否有乘除法.数值范围.加减有无负数.除法有无余数.是否支持分数(真分数,假分数,...):(5选4) 设计思想: 在上一篇已经写出了,在这里就不多做介绍.重点要说的是我在编程过程中遇到的问题.我用的JAVA技术,首先考虑是if条件语句.不断的向下分层.第一个问题就是在打印题目的过程中无法确定每行打印题目数.后来研究了下.才发现应该打印题目不换行.根据打印的题目数换行. 源代码: import j

四则运算2完整版

一.题目要求: 1.题目避免重复: 2.可定制(数量/打印方式): 3.可以控制下列参数: 是否有乘除法.是否有括号. 数值范围.加减有无负数.除法有无余数. 否支持分数 (真分数, 假分数, …).是否支持小数 (精确到多少位).打印中每行的间隔可调整: 二.设计思想 1.题目避免重复 (1)调用随机函数发生器,将生成的运算式用数组存储,将新的运算式与已生成式子做比较,若相同则不输出,不同则输出 2.可定制(数量/打印方式) (1)提示用户输入题目数量,打印方式,从键盘输入 3.(1)是否有乘

四则运算2+psp0级表格

四则运算2 一.题目和要求 题目:写一个能自动生成小学四则运算题目的程序,要求一次输出不少于30道,只能是整数100以内的四则运算(四则运算1升级版) 要求: 1.题目避免重复 2.可定制(数量/打印方式) 3.可以控制下列参数:是否有除法,是否有括号,数值范围,加减有无负数,除法有无余数,是否支持分数,是否支持小数,精确到多少位,打印中每行的间隔 二.题目设计思路 根据第一次的程序实现,已经实现了打印数量上的控制,直接确定了打印列数,其他实现基本功能 第一步:避免题目重复:将打印的结果保存,此