标题:帮忙修改一下代码~大位数减法~
只看楼主
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
结帖率:99.25%
已结贴  问题点数:20 回复次数:11 
帮忙修改一下代码~大位数减法~
刚刚久久的同学仿照久久的大位数加法写了个大位数减法~运行结果出了点问题~还有这个代码没有考虑小数减大数的负数问题~大家帮忙看看~久久要抽空忙别的了~~~

程序代码:
#include<stdio.h>
#include<string.h>
#define N 101                              //先默认数组a比b长

void Init(char a[]);
char* fun(char a[],char b[],char c[]);

int main()
{
    char a[N+1]={0};
    char b[N+1]={0};
    char c[N+2]={0};

    Init(a);
    Init(b);

    printf("%s\n",fun(a,b,c));

    return 0;
}

void Init(char a[])              //输入函数
{
    char c=0;
    int i=1;

    a[0]='0';

    while ((c=getchar())!='\n')
        a[i++]=c;
}

char* fun(char a[],char b[],char c[])
{
    char* pa=a+strlen(a)-1;
    char* pb=b+strlen(b)-1;
    char* pc=c+N-2;
    int k;
    if((*pa-'0')<(*pb-'0'))                                               //修改部分   
    { 
         *pa+=10;
          
          if(*(pa-1)=='0')
          {
                for(k=1;*(pa-k)=='0';k++)
                    *(pa-k)='9';  
               
               *(pa-k)-=1;
          }

          else if(*(pa-1)!='0')
          {
              *(pa-1)-=1;
          }                       //pa变化
      
           *pc=((*pa-'0')-(*pb-'0'));
    }                                                 //  *pc=((*pa-'0')+(*pb-'0'));

       else if((*pa-'0')>=(*pb-'0'))
       { 
          *pc=((*pa-'0')-(*pb-'0'));
       }                                                       //*(pc-1)+=1;
       

       *pc+='0';                                                    // 每次一个运行后都同时向后推
       --pc;

        if (pa!=a)
       --pa;

     if (pb!=b)
         --pb;
   

    return pc+1;
}
搜索更多相关主题的帖子: color 久久 
2017-04-10 21:46
wp231957
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:神界
等 级:版主
威 望:422
帖 子:13681
专家分:53296
注 册:2012-10-18
得分:7 
程序代码:
#include<stdio.h>
#include<string.h>

#define N 101                              

void Init(char* a);
char* fun(char* a,char* b,char* c,char f);
char swap(char* a,char* b);

int main()
{
    char a[N+1]={0};
    char b[N+1]={0};
    char c[N+2]={0};
    Init(a);
    Init(b);
    char f=swap(a,b);  //确保被减数大于等于减数
    printf("%s\n",fun(a,b,c,f));
    return 0;
}

void Init(char* a)              //输入函数
{
    char c=0;
    int i=1;
    a[0]='0';
    while ((c=getchar())!='\n')  a[i++]=c;
}

char swap(char* a,char* b)
{
    char ret='+';
    char tmp[N+2];
    if(strlen(a)<strlen(b) || (strlen(a)==strlen(b) && strcmp(a,b)<0))
    {
        strcpy(tmp,a);
        strcpy(a,b);
        strcpy(b,tmp);
        ret='-';
    }
    return ret;
}
//此函数模拟字符计算2个大数的减法
//传入参数依次为 被减数  减数 差 结果符号
char* fun(char* a,char* b,char* c,char f)
{
    char* pa=a+strlen(a)-1;  //置于字符串尾部 下同
    char* pb=b+strlen(b)-1;
    char* pc=c+N-2;
    char* tpc=pc;  //用于去除前连0
    int flag1=0;
    int flag2=0;
    while(pa>=a)
    {
        if(*pa<*pb  || *pa-flag2-*pb<0)
        {
            flag1=1;
        }
        else flag1=0;
        *pc=*pa-'0'+flag1*10-(*pb-'0')-flag2+'0';
        flag2=flag1;
        pc--;
        if(pb>b) pb--;else *pb='0';  //传入函数前 需确保a>=b 这里处理的是减数没有了的情况
        pa--;
    }
    pc++;
    while(*pc=='0' && pc<tpc) ++pc;  //去除差的前连0
    *(--pc)=f;  //保存差的符号
    return pc;
}



欢迎寻找bug  我测试了几个特殊案例  没有发现bug

DO IT YOURSELF !
2017-04-11 12:04
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:7 
bool stradd( const char* a, char op, const char* b, char* c )
{
    // 判断a、b格式是否正确,并将之正常化,比如"  +0012 "转化为+"12"
    // 假设得到 a_sign, a_begin, a_end,  b_sign, b_begin, b_end

    // 根据 a_sign、op和b_sign联合后的操作符、a是否小于b 这三个条件,规约为6种可能
    // switch( a_sign、op b_sign、a<b? ) --> +(a_+b_)、+(a_-b_)、+(b_-a_)、-(a_+b_)、-(a_-b_)、-(b_-a_)
}
思路简洁,编码繁杂

程序代码:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

//bool stradd( const char* a, char op, const char* b, char* c )
//{
//    // 判断a、b格式是否正确,并将之正常化,比如"  +0012 "转化为+"12"
//    // 假设得到 a_sign, a_begin, a_end,  b_sign, b_begin, b_end
//
//    // 根据 a_sign、op和b_sign联合后的操作符、a是否小于b 这三个条件,规约为6种可能
//    // switch( a_sign、op b_sign、a<b? ) --> +(a_+b_)、+(a_-b_)、+(b_-a_)、-(a_+b_)、-(a_-b_)、-(b_-a_)
//}

#include <stdio.h>
#include <string.h>

static bool stradd_impl_normalize__( const char* s, bool* psign, const char** pbegin, const char** pend )
{
    *pbegin = s + strspn( s, " \f\n\r\t\v" );
    if( **pbegin == '+' )
        *psign=true, ++*pbegin;
    else if( **pbegin == '-' )
        *psign=false, ++*pbegin;
    else
        *psign = true;
    *pbegin += strspn( *pbegin, "0" );
    for( *pend=*pbegin; **pend>='0' && **pend<='9'; ++*pend );
    return (*pend)[strspn(*pend," \f\n\r\t\v")] == '\0';
}

static void stradd_imple_rev__( char* b, char* e )
{
    if( e == b )
    {
        strcpy( b, "0" );
        return;
    }

    for( ; e>b+1 && e[-1]=='0'; --e );

    *e-- = '\0';
    for( ; b<e; ++b,--e)
    {
        char tmp = *b;
        *b = *e;
        *e = tmp;
    }
}

static void stradd_impl_plus__( const char* a_begin, const char* a_end, const char* b_begin, const char* b_end, char* c )
{
    char* pc = c;
    unsigned carry = 0;
    for( ; a_end!=a_begin || b_end!=b_begin; )
    {
        carry += (a_end!=a_begin?*--a_end-'0':0) + (b_end!=b_begin?*--b_end-'0':0);
        *pc++ = carry%10 + '0';
        carry /= 10;
    }
    if( carry )
        *pc++ = carry + '0';
    stradd_imple_rev__(c,pc);
}

static void stradd_impl_minus__( const char* a_begin, const char* a_end, const char* b_begin, const char* b_end, char* c )
{
    char* pc = c;
    unsigned carry = 1;
    for( ; a_end!=a_begin || b_end!=b_begin; )
    {
        carry += 9 + (a_end!=a_begin?*--a_end-'0':0) - (b_end!=b_begin?*--b_end-'0':0);
        *pc++ = carry%10 + '0';
        carry /= 10;
    }
    stradd_imple_rev__(c,pc);
}

bool stradd( const char* a, char op, const char* b, char* c )
{
    bool a_sign; const char* a_begin; const char* a_end;
    bool b_sign; const char* b_begin; const char* b_end;
    {
        if( !stradd_impl_normalize__(a,&a_sign,&a_begin,&a_end) )
            return false;
        if( !stradd_impl_normalize__(b,&b_sign,&b_begin,&b_end) )
            return false;
        if( op!='+' && op!='-' )
            return false;
        b_sign = op=='+' ? b_sign : !b_sign;
    }
    bool a_equal_b = a_end-a_begin==b_end-b_begin && memcmp(a_begin,b_begin,a_end-a_begin)==0;
    bool a_greater_equal_b = (a_end-a_begin>b_end-b_begin) || (a_end-a_begin==b_end-b_begin && memcmp(a_begin,b_begin,a_end-a_begin)>=0);

    switch( a_sign*4 + b_sign*2 + a_greater_equal_b )
    {
    case 4|2|1: // +大 + 小 = 大+小
    case 4|2|0: // +小 + 大 = 小+大
        stradd_impl_plus__(a_begin,a_end,b_begin,b_end,c);
        break;
    case 4|0|1: // +大 - 小 = 大-小
        stradd_impl_minus__(a_begin,a_end,b_begin,b_end,c);
        break;
    case 4|0|0: // +小 - 大 = -(大-小)
        if( a_equal_b )
            strcpy( c, "0" );
        else
            stradd_impl_minus__(b_begin,b_end,a_begin,a_end,(*c++='-',c));
        break;
    case 0|2|1: // -大 + 小 = -(大-小)
        if( a_equal_b )
            strcpy( c, "0" );
        else
            stradd_impl_minus__(a_begin,a_end,b_begin,b_end,(*c++='-',c));
        break;
    case 0|2|0: // -小 + 大 = 大-小
        stradd_impl_minus__(b_begin,b_end,a_begin,a_end,c);
        break;
    case 0|0|1: // -大 - 小 = -(大+小)
    case 0|0|0: // -小 - 大 = -(小+大)
        if( a_end-a_begin==0 && b_end-b_begin==0 )
            strcpy( c, "0" );
        else
            stradd_impl_plus__(a_begin,a_end,b_begin,b_end,(*c++='-',c));
        break;
    }
    return true;
}

#ifndef NDEBUG
#include <stdlib.h>
static void test__( const char* a, char op, const char* b, const char* c )
{
    char tmp[1000];
    if( !stradd(a,op,b,tmp) )
    {
        printf( "%s %c %s = failed\n", a, op, b );
        abort();
    }
    if( strcmp(tmp,c) != 0 )
    {
        printf( "%s %c %s = %s, should be %s\n", a, op, b, tmp, c );
        abort();
    }
}
static void test( void )
{
    test__( "", '+', "", "0" );
    test__( "  ", '+', "  ", "0" );
    test__( " -  ", '+', " - ", "0" );
    test__( "", '-', "", "0" );
    test__( "  ", '-', "  ", "0" );
    test__( " -  ", '-', " - ", "0" );

    for( int a=-1000; a<=+1000; ++a )
    {
        char sa[100];
        sprintf( sa, " %d ", a );
        for( int b=-1000; b<=+1000; ++b )
        {
            char sb[100];
            sprintf( sb, " %d ", b );

            char sc1[100];
            sprintf( sc1, "%d", a+b );

            char sc2[100];
            sprintf( sc2, "%d", a-b );

            test__( sa, '+', sb, sc1 );
            test__( sa, '-', sb, sc2 );
        }
    }
}
#endif

int main( void )
{
    //test();

    char a[101], op, b[101], c[103];
    if( 3==scanf("%s %c %s",a,&op,&b) && stradd(a,op,b,c) )
        puts( c );
}

2017-04-11 13:26
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 2楼 wp231957
附上我同学修改后的代码~天哪~竟然和w版的几乎一样~不要说我重复发帖啊~

程序代码:
#include<stdio.h>
#include<string.h>

#define N 101                              

void Init(char* a);
char* fun(char* a,char* b,char* c,char f);
char swap(char* a,char* b);

int main()
{
    char a[N+1]={0};
    char b[N+1]={0};
    char c[N+2]={0};
    char f=0;

    Init(a);
    Init(b);
    f=swap(a,b);  //确保被减数大于等于减数

    printf("%s\n",fun(a,b,c,f));
    return 0;
}

void Init(char* a)              //输入函数
{
    char c=0;
    int i=1;
    a[0]='0';
    while ((c=getchar())!='\n')  a[i++]=c;
}

char swap(char* a,char* b)
{
    char ret='+';
    char tmp[N+2];
    if(strlen(a)<strlen(b) || (strlen(a)==strlen(b) && strcmp(a,b)<0))
    {
        strcpy(tmp,a);
        strcpy(a,b);
        strcpy(b,tmp);
        ret='-';
    }
    return ret;
}
//此函数模拟字符计算2个大数的减法
//传入参数依次为 被减数  减数 差 结果符号
char* fun(char* a,char* b,char* c,char f)
{
    char* pa=a+strlen(a)-1;  //置于字符串尾部 下同
    char* pb=b+strlen(b)-1;
    char* pc=c+N-2;
    char* tpc=pc;  //用于去除前连0
    int flag1=0;
    int flag2=0;
    while(pa>=a)
    {
        if(*pa<*pb  || *pa-flag2-*pb<0)
        {
            flag1=1;
        }
        else flag1=0;
        *pc=*pa-'0'+flag1*10-(*pb-'0')-flag2+'0';
        flag2=flag1;
        pc--;
        if(pb>b) pb--;else *pb='0';  //传入函数前 需确保a>=b 这里处理的是减数没有了的情况
        pa--;
    }
    pc++;
    while(*pc=='0' && pc<tpc)
        ++pc;  //去除差的前连0

    *(--pc)=f;  //保存差的符号
    return pc;
}

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-11 14:55
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 3楼 rjsp
这个把加法和减法一起做了~高!拜谢了啦~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-11 14:55
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:7 
回复 4楼 九转星河
那么……这岂不是说明你的同学就是W版主。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-11 14:56
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 6楼 renkejun1942
真会开玩笑~你往这方面想会被w版揍的~那同学说其实是一个小问题~就是在原来的代码基础上改了一下~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-11 14:59
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 6楼 renkejun1942
认真看了一下~那同学是昨晚给我答复的~今天w版才回~不过看到注释也一模一样感觉有点不可思议~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-11 15:05
wp231957
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:神界
等 级:版主
威 望:422
帖 子:13681
专家分:53296
注 册:2012-10-18
得分:0 
以下是引用九转星河在2017-4-11 15:05:31的发言:

认真看了一下~那同学是昨晚给我答复的~今天w版才回~不过看到注释也一模一样感觉有点不可思议~~
很明显  我的代码是抄袭你同学的 哈哈

DO IT YOURSELF !
2017-04-11 15:07
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 9楼 wp231957
哇~本来是发一个普通贴~原来还有这种稀奇事~

[此贴子已经被作者于2017-4-11 15:10编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-11 15:07



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-475979-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.190661 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved