- 问题描述:
两个任意长度的正数相减,这两个正数可以带小数点,也可以是整数,请输出结果。 输入的字符串中,不会出现除了数字与小数点以外的其它字符,不会出现多个小数点以及小数点在第一个字符的位置等非法情况,所以考生的程序中无须考虑输入的数值字符串非法的情况。
详细要求以及约束:
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。
- 要求实现函数:
Prototype : int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult)
Input Param : const char *pMinuend 被减数,以\0表示字符串结束
const char *pSubtrahend 减数,以\0表示字符串结束
Output : char **ppResult 减法结果,必须以\0表示字符串结束
Return Value : 成功返回0 失败返回-1
代码如下:
#include <stdlib.h>
#include <string>
//得到小数点的位置
int getDot(const char *pMinuend)//小数点计算函数
{
int i=0;
while(*(pMinuend+i) != '.' && i< strlen(pMinuend))
{
i++;
}
return i;
}
/*****************************************************************************
Description : 两个任意长度的正数相减
Prototype : int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult)
Input Param : const char *pMinuend 被减数,以\0表示字符串结束
const char *pSubtrahend 减数,以\0表示字符串结束
Output : char **ppResult 减法结果,必须以\0表示字符串结束
Return Value : 成功返回0 失败返回-1
*****************************************************************************/
int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult)
{
/* 在这里实现功能 */
if(pMinuend == NULL || pSubtrahend == NULL || pMinuend[0] == '\0' || pSubtrahend[0] == '\0')
{
return -1;
}
else
{
//1.得到pMinuend和pSubtrahend的小数点位置
int dot1 = getDot(pMinuend),dot2 = getDot(pSubtrahend);
//2.得到pMinuend和pSubtrahend的长度
int len1 = strlen(pMinuend),len2 = strlen(pSubtrahend);
//3.得到pMinuend的整数部分长度和小数部分长度
int pMinuend_big=dot1,pMinuend_small=len1-dot1-1;
if(pMinuend_small < 0) pMinuend_small=0;
//4.得到pSubtrahend的整数部分长度和小数部分长度
int pSubtrahend_big=dot2,pSubtrahend_small=len2-dot2-1;
if(pSubtrahend_small < 0) pSubtrahend_small=0;
//5.得到统一格式后的小数点位置
int dot3=dot1 > dot2 ? dot1:dot2;
//6.得到统一格式后的小数部分长度
int small_len=pMinuend_small > pSubtrahend_small ? pMinuend_small:pSubtrahend_small;
//7.得到统一格式后的字符串长度
int len3;
if(small_len == 0)
{
//无小数部分
len3=dot3;
}
else
{
len3=dot3+small_len+1;
}
//8.定义三个统一格式后的字符串,分别存储减数,被减数,和结果,并初始化为0
char* str1 = (char *)malloc(len3+1);//加1为了存结束符
char* str2 = (char *)malloc(len3+1);
char* result = (char *)malloc(len3+1);
memset(str1,'0',len3);
memset(str2,'0',len3);
memset(result,'0',len3);
str1[len3] = '\0';
str2[len3] = '\0';
result[len3] = '\0';
//9.将数据存入到统一格式后的字符串中
int i,j;
//先存被减数的
j=dot3-1;
for(i=dot1-1;i>=0;i--)
{
str1[j]=pMinuend[i];
j--;
}
j=dot3+1;
for(i=dot1+1;i<len1;i++)
{
str1[j]=pMinuend[i];
j++;
}
if(str1[dot3] != '\0')
{
str1[dot3]='.';
}
//再存减数
j=dot3-1;
for(i=dot2-1;i>=0;i--)
{
str2[j]=pSubtrahend[i];
j--;
}
j=dot3+1;
for(i=dot2+1;i<len2;i++)
{
str2[j]=pSubtrahend[i];
j++;
}
if(str2[dot3] != '\0')
{
str2[dot3]='.';
}
//10.定义两个指针,分别指向最大,最小值,定义一个标志,判断被减数是否小于减数
char *max,*min;
int flag=0;//默认不小于
if(strcmp(str1,str2) >= 0)
{
max=str1;
min=str2;
}
else
{
max=str2;
min=str1;
flag=1;
}
//11.定义一个函数,大数减去小数,结果保存在,result中,从右往左进行计算,并考虑进位问题
//i标记最后一位,j为进位,temp为结果缓存
int temp;
for(i=len3-1;i>=0;i--)
{
if(max[i] == '.')
{
result[i]='.';
}
else if(max[i]-min[i] >= 0)
{
temp=max[i]-min[i];
result[i]=temp+'0';
}
else//考虑进位
{
temp=10+max[i]-min[i];
//标记到可以提供进位的下标
j=i-1;
while(max[j] < '1')
{
j--;
}
//进位之后,max[j]-1;
max[j]=max[j]-1;
//往后修改各个位数,直到i-1
j=j+1;
while(j != i)
{
if(max[j]=='.')
{
j++;
}
else
{
max[j]='9';
j++;
}
}
result[i]=temp+'0';
}
// result[i]=temp+'0';
}
//12.将result中的字符去掉首位和末尾的0
//去掉首位的0
i=0;
int length=len3;
while(result[i] == '0')
{
i++;
length--;
}
//去掉末尾的0
j=len3-1;
while(result[j] == '0')
{
j--;
length--;
}
//如果第一个是小数点,加上0,即后退一个下标
if(result[i] == '.')
{
i--;
length++;
}
//如果最后一个是小数点,删掉
if(result[j] == '.')
{
j--;
length--;
}
//13.把i到j的范围赋值给p,并考虑正负数
char*p=(char*)malloc(length*sizeof(char)+2);
if(flag == 1)
{
//分配多一个空间,从1开始赋值
int m=1;
for(int k=i;k<=j;k++)
{
p[m]=result[k];
m++;
}
p[0]='-';
p[m]='\0';
}
else
{
int m=0;
for(int k=i;k<=j;k++)
{
p[m]=result[k];
m++;
}
p[m]='\0';
}
//13.将result赋值给*ppResult
*ppResult=p;
//14.释放内存
free(str1);
free(str2);
free(result);
return 0;
}
}
#include <string>
//得到小数点的位置
int getDot(const char *pMinuend)//小数点计算函数
{
int i=0;
while(*(pMinuend+i) != '.' && i< strlen(pMinuend))
{
i++;
}
return i;
}
/*****************************************************************************
Description : 两个任意长度的正数相减
Prototype : int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult)
Input Param : const char *pMinuend 被减数,以\0表示字符串结束
const char *pSubtrahend 减数,以\0表示字符串结束
Output : char **ppResult 减法结果,必须以\0表示字符串结束
Return Value : 成功返回0 失败返回-1
*****************************************************************************/
int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult)
{
/* 在这里实现功能 */
if(pMinuend == NULL || pSubtrahend == NULL || pMinuend[0] == '\0' || pSubtrahend[0] == '\0')
{
return -1;
}
else
{
//1.得到pMinuend和pSubtrahend的小数点位置
int dot1 = getDot(pMinuend),dot2 = getDot(pSubtrahend);
//2.得到pMinuend和pSubtrahend的长度
int len1 = strlen(pMinuend),len2 = strlen(pSubtrahend);
//3.得到pMinuend的整数部分长度和小数部分长度
int pMinuend_big=dot1,pMinuend_small=len1-dot1-1;
if(pMinuend_small < 0) pMinuend_small=0;
//4.得到pSubtrahend的整数部分长度和小数部分长度
int pSubtrahend_big=dot2,pSubtrahend_small=len2-dot2-1;
if(pSubtrahend_small < 0) pSubtrahend_small=0;
//5.得到统一格式后的小数点位置
int dot3=dot1 > dot2 ? dot1:dot2;
//6.得到统一格式后的小数部分长度
int small_len=pMinuend_small > pSubtrahend_small ? pMinuend_small:pSubtrahend_small;
//7.得到统一格式后的字符串长度
int len3;
if(small_len == 0)
{
//无小数部分
len3=dot3;
}
else
{
len3=dot3+small_len+1;
}
//8.定义三个统一格式后的字符串,分别存储减数,被减数,和结果,并初始化为0
char* str1 = (char *)malloc(len3+1);//加1为了存结束符
char* str2 = (char *)malloc(len3+1);
char* result = (char *)malloc(len3+1);
memset(str1,'0',len3);
memset(str2,'0',len3);
memset(result,'0',len3);
str1[len3] = '\0';
str2[len3] = '\0';
result[len3] = '\0';
//9.将数据存入到统一格式后的字符串中
int i,j;
//先存被减数的
j=dot3-1;
for(i=dot1-1;i>=0;i--)
{
str1[j]=pMinuend[i];
j--;
}
j=dot3+1;
for(i=dot1+1;i<len1;i++)
{
str1[j]=pMinuend[i];
j++;
}
if(str1[dot3] != '\0')
{
str1[dot3]='.';
}
//再存减数
j=dot3-1;
for(i=dot2-1;i>=0;i--)
{
str2[j]=pSubtrahend[i];
j--;
}
j=dot3+1;
for(i=dot2+1;i<len2;i++)
{
str2[j]=pSubtrahend[i];
j++;
}
if(str2[dot3] != '\0')
{
str2[dot3]='.';
}
//10.定义两个指针,分别指向最大,最小值,定义一个标志,判断被减数是否小于减数
char *max,*min;
int flag=0;//默认不小于
if(strcmp(str1,str2) >= 0)
{
max=str1;
min=str2;
}
else
{
max=str2;
min=str1;
flag=1;
}
//11.定义一个函数,大数减去小数,结果保存在,result中,从右往左进行计算,并考虑进位问题
//i标记最后一位,j为进位,temp为结果缓存
int temp;
for(i=len3-1;i>=0;i--)
{
if(max[i] == '.')
{
result[i]='.';
}
else if(max[i]-min[i] >= 0)
{
temp=max[i]-min[i];
result[i]=temp+'0';
}
else//考虑进位
{
temp=10+max[i]-min[i];
//标记到可以提供进位的下标
j=i-1;
while(max[j] < '1')
{
j--;
}
//进位之后,max[j]-1;
max[j]=max[j]-1;
//往后修改各个位数,直到i-1
j=j+1;
while(j != i)
{
if(max[j]=='.')
{
j++;
}
else
{
max[j]='9';
j++;
}
}
result[i]=temp+'0';
}
// result[i]=temp+'0';
}
//12.将result中的字符去掉首位和末尾的0
//去掉首位的0
i=0;
int length=len3;
while(result[i] == '0')
{
i++;
length--;
}
//去掉末尾的0
j=len3-1;
while(result[j] == '0')
{
j--;
length--;
}
//如果第一个是小数点,加上0,即后退一个下标
if(result[i] == '.')
{
i--;
length++;
}
//如果最后一个是小数点,删掉
if(result[j] == '.')
{
j--;
length--;
}
//13.把i到j的范围赋值给p,并考虑正负数
char*p=(char*)malloc(length*sizeof(char)+2);
if(flag == 1)
{
//分配多一个空间,从1开始赋值
int m=1;
for(int k=i;k<=j;k++)
{
p[m]=result[k];
m++;
}
p[0]='-';
p[m]='\0';
}
else
{
int m=0;
for(int k=i;k<=j;k++)
{
p[m]=result[k];
m++;
}
p[m]='\0';
}
//13.将result赋值给*ppResult
*ppResult=p;
//14.释放内存
free(str1);
free(str2);
free(result);
return 0;
}
}