zoukankan      html  css  js  c++  java
  • 长整数相加运算(内含减法)。。= =

    对长整数进行运算很变态,由于不能限制位数,所以一般采用链表进行计算,并且得自己设计进位退位的具体步骤,中间还有很多特殊情况和变态的情形得考虑进去。。。= =。WTF!

    在之前的一篇blog中曾经探讨过这个问题,但是结果都不是很完善,这次的结果应该算是比较完美的了,理论上只要你的内存足够大,那么就能进行无限数位的长整数运算。

    如有纰漏欢迎指出~~~

    进行减法运算只需对被减的整数首位添加“-”即可

    代码
    1 /*
    2 A,B均为整数,则运算时输入: A;B;
    3 A,B中的隔位符号“,”可加可不加
    4  */
    5 #include <stdio.h>
    6 #include <stdlib.h>
    7 typedef struct Node //定义节点结构
    8  {
    9 int num;
    10 struct Node *prev;
    11 struct Node *next;
    12 }Node;
    13 Node *create();
    14 Node *add(Node *A,Node *B);
    15 Node *minus(Node *A,Node *B);
    16  void main()
    17 {
    18 int i=0;
    19 Node *P,*Q,*R,*TEMP,*r;
    20 P=create();
    21 Q=create();
    22 if (P->num/Q->num==1) //对进行的运算进行分类,同号则相加,异号则相减
    23   R=add(P,Q);
    24 else
    25 R=minus(P,Q);
    26 if (R->num==-2||R->num==-4) //结果是负数时在首位输出“-”
    27   printf("-");
    28 TEMP=R; //在整数链表中插入“,”
    29   while (TEMP->next)
    30 TEMP=TEMP->next;
    31 while (TEMP->prev)
    32 {
    33 if (i==3)
    34 {
    35 i=0;
    36 r=(Node*)malloc(sizeof(Node));
    37 r->next=TEMP;
    38 r->num=',';
    39 r->prev=TEMP->prev;
    40 TEMP->prev->next=r;
    41 TEMP->prev=r;
    42 TEMP=r->prev;
    43 continue;
    44 }
    45 else
    46 {
    47 i++;
    48 TEMP=TEMP->prev;
    49 }
    50 }
    51 R=R->next;
    52 while (R) //输出结果,当因子为数字时以数字形式输出,否则以字符形式输出
    53   { //因而能够将之前插入的“,”成功输出
    54 if (R->num!=',')
    55 printf("%d",R->num);
    56 else
    57 {
    58 if (R->prev->num>=0) //排除在首位输出“,”的情况
    59 printf("%c",R->num);
    60 }
    61 R=R->next;
    62 }
    63 printf("\n");
    64 }
    65 Node *create() //创建整数动态链表,每个节点中存储一位数字
    66 {
    67 char c;
    68 Node *A,*p,*temp;
    69 A=(Node*)malloc(sizeof(Node));
    70 A->num=-1;
    71 A->prev=NULL;
    72 p=A;
    73 c=getchar();
    74 while (c!=59) //判断是否结束输入
    75 {
    76 if (c=='-')
    77 {
    78 A->num=-2;
    79 c=getchar();
    80 }
    81 else //将输入的数字存储在动态链表中
    82 {
    83 if (c>='0'&&c<='9')
    84 {
    85 temp=(Node*)malloc(sizeof(Node));
    86 temp->num=c-48; //此处将字符形态的数字转换为真实的数字
    87 temp->prev=p;
    88 p->next=temp;
    89 p=temp;
    90 c=getchar();
    91 }
    92 else
    93 c=getchar(); //排除输入的字符“,”
    94 }
    95 }
    96 p->next=NULL;
    97 p=A;
    98 return p;
    99 }
    100 Node *add(Node *A,Node *B)
    101 {
    102 Node *TEMP,*p,*q,*r;
    103 int t=0;
    104 p=A;
    105 q=B;
    106 while (p&&q)
    107 {
    108 if (p->next==NULL&&q->next!=NULL)
    109 {
    110 TEMP=A;
    111 A=B;
    112 B=TEMP;
    113 break;
    114 };
    115 if (p->next==NULL&&q->next==NULL)
    116 t=1; //t为一个判断因子,用来判断是否是同位数的数字相加
    117 p=p->next;
    118 q=q->next;
    119 }
    120 p=A;
    121 q=B;
    122 while (p->next) //分别存入两整数最后一位的节点地址,方便后面有低位到高位进行运算
    123 {
    124 p=p->next;
    125 }
    126 while (q->next)
    127 {
    128 q=q->next;
    129 }
    130 while(p->prev&&q->prev)
    131 {
    132 if ((p->num)>9)
    133 {
    134 if (p->prev==A) //如果最高位需要进位则创建一个新节点存储结果
    135 {
    136 r=(Node*)malloc(sizeof(Node));
    137 r->prev=A;
    138 r->num=1;
    139 r->next=p;
    140 p->num-=10;
    141 p->prev=r;
    142 A->next=r;
    143 }
    144 else
    145 {
    146 p->num-=10;
    147 (p->prev->num)++;
    148 }
    149 }
    150 p->num+=q->num;
    151 if ((p->num)>9) //进位需要进行的操作
    152 {
    153 if (p->prev==A)
    154 {
    155 r=(Node*)malloc(sizeof(Node));
    156 r->prev=A;
    157 r->num=1;
    158 r->next=p;
    159 p->num-=10;
    160 p->prev=r;
    161 A->next=r;
    162 }
    163 else
    164 {
    165 p->num-=10;
    166 (p->prev->num)++;
    167 }
    168 }
    169 p=p->prev;
    170 q=q->prev;
    171 }
    172 if (t!=1) //不是同位数的数字相加则必须得将位数长的数字该进位的进位到底
    173 {
    174 while (p->prev->prev)
    175 {
    176 if (p->num>9)
    177 {
    178 p->num-=10;
    179 p->prev->num++;
    180 }
    181 p=p->prev;
    182 }
    183 }
    184 return A;
    185 }
    186 Node *minus(Node *A,Node *B) //大致思路同加法,只不过进位换成了退位
    187 {
    188 Node *TEMP,*p,*q;
    189 int temp;
    190 p=A;
    191 q=B;
    192 while (p&&q)
    193 {
    194 if (p->next==NULL&&q->next!=NULL)
    195 {
    196 TEMP=A;
    197 A=B;
    198 B=TEMP;
    199 break;
    200 }
    201 if (p->next==NULL&&q->next==NULL)
    202 {
    203 if (A->num==-2)
    204 {
    205 TEMP=A;
    206 A=B;
    207 B=TEMP;
    208 A->num=-3;
    209 B->num=-4;
    210 break;
    211 }
    212 else
    213 {
    214 A->num=-3;
    215 B->num=-4;
    216 break;
    217 }
    218 }
    219 p=p->next;
    220 q=q->next;
    221 }
    222 p=A;
    223 q=B;
    224 while (p->next)
    225 {
    226 p=p->next;
    227 }
    228 while (q->next)
    229 {
    230 q=q->next;
    231 }
    232 if (A->num!=-3)
    233 {
    234 while (p->prev&&q->prev)
    235 {
    236 temp=p->num;
    237 p->num-=q->num;
    238 if (p->num<0)
    239 {
    240 p->num=temp+10-q->num;
    241 p->prev->num--;
    242 }
    243 p=p->prev;
    244 q=q->prev;
    245 }
    246 while (p->prev->prev)
    247 {
    248 if (p->num<0)
    249 {
    250 p->num+=10;
    251 p->prev->num--;
    252 }
    253 p=p->prev;
    254 }
    255 }
    256 else
    257 {
    258 while (p->prev&&q->prev)
    259 {
    260 temp=p->num;
    261 p->num-=q->num;
    262 if (p->num<0&&p->prev!=A)
    263 {
    264 p->num=temp+10-q->num;
    265 p->prev->num--;
    266 }
    267 if (p->num<0&&p->prev==A)
    268 {
    269 A->num=-4;
    270 p->num=-p->num;
    271 }
    272 p=p->prev;
    273 q=q->prev;
    274 }
    275 }
    276 if (A->next->num==0) //最后将首位为0的从链表中舍去
    277 {
    278 p=A->next;;
    279 while (p)
    280 {
    281 if (p->num==0&&p->next!=NULL)
    282 {
    283 A->next=p->next;
    284 A->next->prev=A;
    285 }
    286 else
    287 break;
    288 p=p->next;
    289 }
    290 }
    291 return A;
    292 }
  • 相关阅读:
    jQuery Validate input是动态变化的
    flexigrid随手记
    今日随笔:scrollTop与overflow
    滚动条自动滚到底
    团队项目计划会议
    电梯演讲视频+原型展示
    NABCD项目分析
    团队第一次会议纪要
    软件开发团队介绍
    2020年11月24日
  • 原文地址:https://www.cnblogs.com/kanone/p/1875339.html
Copyright © 2011-2022 走看看