/*任意位数整数减法,双向链表实现,无法处理负数,如果减数小于被减数,则显示结果的绝对值*/
#include<stdio.h>
#include<stdlib.h>
typedef unsigned char byte;
typedef struct Dgt //每一位数字一个节点
{
struct Dgt * prev;
struct Dgt * next;
byte val;
}Digit,*P_Digit;
P_Digit CreateDigit(int *); //产生链表
P_Digit subtraction(P_Digit, P_Digit); //相减
inline int IsDigit(const char); //判断输入字符是否是数字
P_Digit endDigit(const P_Digit); //找到最后一位
void disp(const P_Digit); //显示
void addZero(P_Digit, P_Digit);//被减数高位补0
void borrowDigit(P_Digit);//借位
void destroy(P_Digit); //销毁链表
int isGT(P_Digit, P_Digit);//判断被减数是否大于减数,大于返回1,小于等于返回0
int main(int argc, char *argv[])
{
int min_bit = 0, sub_bit = 0;//被减数位数,减数位数
P_Digit minuend = NULL, subtractor = NULL, result = NULL;//被减数,减数,结果
puts("Any bits integer subtraction");
subtractor = CreateDigit(&sub_bit);
minuend = CreateDigit(&min_bit);
disp(subtractor);
disp(minuend);
result = subtraction(minuend, subtractor);
disp(result);
destroy(minuend);
destroy(subtractor);
destroy(result);
return 0;
}
P_Digit CreateDigit(int *bit)
{
int ipt = 0;
P_Digit head = NULL,cur = NULL;
char ch;
puts("Enter a digit,q to quit!");
head = (P_Digit)calloc(1,sizeof(Digit));
head->prev = NULL;
head->next = NULL;
cur = head;
while((ch = getchar()) != 'q' && IsDigit(ch))
{
++(*bit);
P_Digit new = NULL;
new = (P_Digit)calloc(1,sizeof(Digit));
new->val = ch - 48;
new->next = NULL;
cur->next = new;
new->prev = cur;
cur = new;
}
head->val = *bit;
return head;
}
void destroy(P_Digit head)
{
P_Digit cur = head;
while(cur != NULL)
{
free(cur);
cur = cur->next;
}
}
void disp(const P_Digit head)
{
P_Digit cur = head->next;
printf("bits : %d integer : ",head->val);
while(cur != NULL)
{
printf("%d",cur->val);
cur = cur->next;
}
putchar('\n');
}
inline int IsDigit(const char ch)
{
if(ch >= '0' && ch <= '9')
return 1;
else
return 0;
}
int isGT(P_Digit min, P_Digit sub)//判断被减数是否大于减数,大于返回1,小于等于返回0
{
P_Digit min_cur = min->next, sub_cur = sub->next;
if(min->val > sub->val)
return 1;
else if(min->val < sub->val)
return 0;
else
{
while(min_cur != NULL)
{
if(min_cur->val > sub_cur->val)
return 1;
min_cur = min_cur->next;
sub_cur = sub_cur->next;
}
return 0;
}
}
P_Digit endDigit(const P_Digit head)//找到最后一位
{
P_Digit cur = head;
while(cur->next != NULL)
{
cur = cur->next;
}
return cur;
}
void addZero(P_Digit min_head, P_Digit sub_head)//被减数高位补0
{
int num = sub_head->val - min_head->val;
P_Digit cur = min_head;
while(num != 0)
{
P_Digit new = NULL;
new = (P_Digit)calloc(1,sizeof(Digit));
new->val = 0;
cur->next->prev = new;
new->next = cur->next;
new->prev = cur;
cur->next = new;
--num;
}
}
void borrowDigit(P_Digit pd)//借位
{
pd->val += 10;
if(pd->prev->val == 0) //如果前一位是0,继续向前借位,并且此位减一
{
borrowDigit(pd->prev);
--(pd->prev->val);
}
else
--(pd->prev->val);
}
P_Digit subtraction(P_Digit minuend, P_Digit subtractor)
{
P_Digit result_head = NULL;
result_head = (P_Digit)calloc(1,sizeof(Digit));
result_head->prev = NULL;
result_head->next = NULL;
if(isGT(minuend, subtractor))//减数小于被减数,交换两数
{
P_Digit swap = subtractor;
subtractor = minuend;
minuend = swap;
}
P_Digit min_cur = endDigit(minuend);//从低位开始减
P_Digit sub_cur = endDigit(subtractor);
addZero(minuend, subtractor);//位数不同则被减数高位补零
while(sub_cur->prev != NULL)
{
P_Digit new = NULL;
new = (P_Digit)calloc(1,sizeof(Digit));
if(result_head->next == NULL)//在头结点之后插入,便于显示
{
new->next = NULL;
result_head->next = new;
new->prev = result_head;
}
else
{
result_head->next->prev = new;
new->next = result_head->next;
new->prev = result_head;
result_head->next = new;
}
if(sub_cur->val < min_cur->val)
{
borrowDigit(sub_cur);
new->val = sub_cur->val - min_cur->val;
}
else
{
new->val = sub_cur->val - min_cur->val;
}
min_cur = min_cur->prev;
sub_cur = sub_cur->prev;
}
return result_head;
}
面试题目任意位数整数减法
最新推荐文章于 2025-05-12 22:00:00 发布