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 );
}