大正数减法(华为2013校园招聘上机笔试题 )

来源:互联网 发布:kettle 大数据 编辑:程序博客网 时间:2024/05/18 02:53

问题描述:    
两个任意长度的正数相减,这两个正数可以带小数点,也可以是整数,请输出结果。 输入的字符串中,不会出现除了数字与小数点以外的其它字符,不会出现多个小数点以及小数点在第一个字符的位置等非法情况,所以考生的程序中无须考虑输入的数值字符串非法的情况。 
详细要求以及约束:
1.输入均为正数,但输出可能为负数; 
2.输入输出均为字符串形式;
3.如果输出是正数则不需要带符号,如果为负数,则输出的结果字符串需要带负号
例如:2.2-1.1 直接输出为“1.1”,1.1-2.2 则需要输出为“-1.1”
 4.输出的结果字符串需要过滤掉整数位前以及小数位后无效的0,小数位为全0的,直接输出整数位
例如相减结果为11.345,此数值前后均不可以带0,“011.345”或者“0011.34500”等等前后带无效0的均视为错误 输出。例如1.1-1.1结果为0.0,则直接输出0。
要求实现函数:
void Decrease(char *input1, char*input2, char *output)
【输入】 char *iinput1 被减数
char*nput2 减数 
【输出】 char *output 减法结果
【返回】 无
示例
输入:char *input1="2.2" 
char *input2="1.1"
输出:char*output="1.1"
输入:char *input1="1.1" 
char *input2="2.2"
输出:char *output="-1.1"

以上摘自 http://blog.csdn.net/lanyan822/article/details/7983832 ,但是考虑到没有给出这个的源代码,自己随手写了一个,写得不好,仅供娱乐,欢迎大神指点。

 

 

这次的代码很长,我是为了写的可读性更高一点,很多地方比较累赘而且用的方法比较直接,也是我一开始直接想到的。如果有更好的方法希望大家提供哈...

//正数减法//问题描述:    //两个任意长度的正数相减,这两个正数可以带小数点,也可以是整数,请输出结果。//输入的字符串中,不会出现除了数字与小数点以外的其它字符,不会出现多个小数点以及小数点在第一个字符的位置等非法情况,所以考生的程序中无须考虑输入的数值字符串非法的情况。 //详细要求以及约束://1.输入均为正数,但输出可能为负数; //2.输入输出均为字符串形式;//3.如果输出是正数则不需要带符号,如果为负数,则输出的结果字符串需要带负号//例如:2.2-1.1 直接输出为“1.1”,1.1-2.2 则需要输出为“-1.1”// 4.输出的结果字符串需要过滤掉整数位前以及小数位后无效的0,小数位为全0的,直接输出整数位//例如相减结果为11.345,此数值前后均不可以带0,“011.345”或者“0011.34500”等等前后带无效0的均视为错误 输出。例如1.1-1.1结果为0.0,则直接输出0。//要求实现函数://void Decrease(char *input1, char*input2, char *output)//【输入】 char *iinput1 被减数//char*nput2 减数 //【输出】 char *output 减法结果//【返回】 无//示例//输入:char *input1="2.2" //char *input2="1.1"//输出:char*output="1.1"//输入:char *input1="1.1" //char *input2="2.2"//输出:char *output="-1.1"#include <algorithm>#include <assert.h>//得到小数点的位置int getDot(char *input1)//小数点计算函数{return find(input1,input1+strlen(input1),'.') - input1;}void Decrease(char *input1, char*input2, char *output){assert(input1 != NULL && input2 != NULL && output != NULL);//假设三个参数都不为空//1.小数点对其int dot1 = getDot(input1),dot2 = getDot(input2);//2.小数点对其初始化两个char数组,方便之后运算。长度为双方可能的最大位数int length = ((strlen(input1)-dot1)>(strlen(input2)-dot2)?(strlen(input1)-dot1):(strlen(input2)-dot2))/*小数部分最长的值*/+(dot1>dot2?dot1:dot2)/*整数部分最长的值*/+1/*可能产生的符号位与小数点*/;char *str1,*str2,*result;str1 = (char *)malloc(length+1);//加1为了存结束符str2 = (char *)malloc(length+1);result = (char *)malloc(length+1);memset(str1,'0',length);memset(str2,'0',length);memset(result,'0',length);str1[length] = '\0';str2[length] = '\0';result[length] = '\0';//3.得出每个字符串小数点对其后的位置,但是不拷贝最后一个'\0'结束符memcpy(&str1[abs(dot1>dot2?dot1:dot2-dot1)+1],input1,strlen(input1));memcpy(&str2[abs(dot1>dot2?dot1:dot2-dot2)+1],input2,strlen(input2));//4.得到两数之间较大的数,为了保证始终大数减小数,省的借位情况复杂int isPlus = true;//如果被减数更大则为真char *max = str1,*min = str2;for(int i = 1;i < length;++i){if(str1[i] > str2[i]){max = str1;min = str2;break;}else if(str1[i] < str2[i]){isPlus = false;max = str2;min = str1;break;}else if(i == length - 1){//两个字符串数字相等output[0] = '0';output[1] = '\0';return ;}}//把没有小数点的全部补齐result[dot1>dot2?dot1:dot2 + 1] = '.';max[dot1>dot2?dot1:dot2 + 1] = '.';min[dot1>dot2?dot1:dot2 + 1] = '.';//5.开始运算for(int i = length-1;i > 0;--i){//开始从右到左开始减if(max[i] == '.'){result[i] == '.';continue;}int temp;temp = max[i] - min[i];if(temp < 0){//如果不够减时向高位借数int j = i;while(max[j] == '0' || max[j] == '.'/* && j != 0*/){//找到可以借位的数为止,因为输入的都是整数,所以不做更多讨论if(max[j] == '0'){max[j] = '9';}j--;}max[j]--;temp += 10;}result[i] = temp + '0';}if(!isPlus)output[0] = '-';//6.把结果字符格式化给output字符串for(unsigned int i = strlen(result);i >= 0;++i){//清除末尾0或最后一位是小数点if(result[i] == '0' || result[i] == '.')result[i] = '\0';elsebreak;}unsigned int first = 1;//记录第一位有效位的起始位置while(result[first] == '0'){first++;}strcpy(output,&result[first]);}int _tmain(int argc, _TCHAR* argv[]){char r[10000];Decrease("2.2", "1.1",r);cout<<r;return 0;}


 

原创粉丝点击