岚朋友


私信TA

用户名:a475308928

访问量:1606

签 名:

等  级
排  名 78
经  验 9662
参赛次数 0
文章发表 11
年  龄 0
在职情况 学生
学  校 ???
专  业 软件工程

  自我简介:

TA的其他文章

位运算 26行
浏览:59

代码解释都用注释写在旁边了

解题思路:
一步步来就没问题

注意事项:
上题过了这题就一遍过;

可能要有的:

①忽略前导0 如009+001-002这样的

②直接回车也输出0

参考代码:

#include<stdio.h>
const int N=1e4+5;//上题用的常数
inline void swap(int &a,int &b){int c=a;a=b;b=c;}//交换
inline void deal(int *a)//把009变成900的左右颠倒函数
{ int len=a[0]>>1;//移位运算符,相当于/2
  for(int i=1;i<=len;++i)swap(a[i],a[a[0]+1-i]);
}
void out(int *a){for(int i=a[0]?a[0]:1;i>0;--i)printf("%d",a[i]);/*putchar(10);*/}//输出结果的函数
inline void add(int *a,int *b)//高精度加法
{ a[0]=(a[0]>b[0]?a[0]:b[0])+1;//取两个长度中较长的并且+1,因为最高的位数在相加时可能会进1  如9+1=10
  b[0]=0;//清理数组
  for(int i=1;i<=a[0];++i)
  { a[i]+=b[i];
    b[i]=0;//顺便清理数组
    if(a[i]>9)a[i]-=10,++a[i+1];//进位
  }
  while(a[0]>1&&!a[a[0]])--a[0];//至少保留1位,同时去除前导0
}
inline void subtraction(int *a,int *b)
{ a[0]=a[0]>b[0]?a[0]:b[0];//从上面抄下来的。因为是减法没有+1也行
  b[0]=0;//清理数组
  for(int i=1;i<=a[0];++i)
  { a[i]-=b[i];
    b[i]=0;//顺便清理数组
    if(a[i]<0)a[i]+=10,--a[i+1];//借位
  }
  while(a[0]>1&&!a[a[0]])--a[0];//至少保留1位,同时去除前导0
}
inline void yunsuan(const char &op,int *a,int *b)
{ deal(b);//运算前先处理b数组
  switch(op)//根据上次的运算符决定进行什么运算
  { case('+'):add(a,b);return;
    case('-'):subtraction(a,b);return;
    default:return; 
  }
}
inline bool check(const char &k,char &op,int *a,int *b)//看看这个是运算符还是数字还是别的
{ switch(k)
  { case('+'):yunsuan(op,a,b),op=k;return 1;//运算在前面是因为op是上次没算的运算符。  实际上1+1-1 是读到减号的时候才开始算加号的
    case('-'):yunsuan(op,a,b),op=k;return 1;
    case('*'):yunsuan(op,a,b),op=k;return 1;
    case('/'):yunsuan(op,a,b),op=k;return 1;
    case('^'):yunsuan(op,a,b),op=k;return 1;
    default:return 0;
  }//1是运算符,0不是
}
int a[N],b[N];//a是结果数组,b是临时数组,a[0],b[0]为数组长度
char op,k;//op是上次的运算符,k是用来读字符的变量
bool key,mark;//key用于去除前导0,mark判断a有没有被处理过,处理过才能用out()输出
main()
{ while(k!=-1&&k!=10&&~(k=getchar()))//如果读取到回车或EOF就退出
  { if(check(k,op,a,b))//看看这个是运算符还是数字还是别的
    { deal(a);
      key=0;//每次读取数字都要关闭,说明还没处理前导0
      mark=1;//处理过a数组的标志
      while(~(k=getchar())&&k!=10)//不读取EOF和回车
      if(check(k,op,a,b))key=0;//读取的是个运算符,说明要接受新数字,将key关闭
      else if(k>=48&&k<=57)//如果是数字
             if(key)b[++b[0]]=k-48;//如果不是第一次碰到非0就记录
             else if(k!=48)b[++b[0]]=k-48,key=1;//第一次碰到非0的数字记录,并且把key打开
    }
    else if(k>=48&&k<=57)//如果是数字
           if(key)a[++a[0]]=k-48;//如果不是第一次碰到非0就记录
           else if(k!=48)a[++a[0]]=k-48,key=1;//第一次碰到非0的数字记录,并且把key打开
  } 
  if(!mark)deal(a);//没处理就处理一下
  yunsuan(op,a,b);//最后没有运算符,不会自动进行计算,手动补上一步
  out(a);//输出
}


 

0.0分

2 人评分

  评论区

  • «
  • »