• 实验:线性表及其应用


    一、实验内容

    【问题描述】 设计一个实现任意长的整数进行加法运算的演示程序

    【基本要求】 利用双向循环链表实现长整数的存储,每个结点含一个整形变量。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。

    【测试数据】

    100;应输出“0”

    2-2345,6789-7654,3211;应输出“-1,0000,0000”

    3-9999,99991,0000,0000,0000;应输出“9999,0000,0001”

    41,0001,0001-1,0001,0001;应输出“0”

    51,0001,0001-1,0001,0000;应输出“1”

    6-9999,9999,9999-9999,9999,9999;应输出-1,9999,9999,9998”

    71,0000,9999,99991;应输出“1,0001,0000,0000”

    二、实验目的

    熟悉掌握链表的基本操作

    .培养运用线性表解决问题的能力。

    三、实验文档:

    1. 概要设计(文字性地说明解决问题的具体方法和步骤)

    a) 创建双向链表结点的结构体

    b) 声明三条链表:L1L2L

    c) 每一个结点的数据域只存四位数

    d) 链表的生长方向为顺序,相加时逆序,即由尾到头,头结点存储符号和位数信息

    e) 每一次相加时,若符号相同,则直接相加,用n=data/1,0000检查是否进位,若进位(n>1)L1链的前一结点data+1,

    f) 若符号相异,则绝对值大的作为被减数,事后确定符号,借位时,若果前一结点不是 head,则data=1 0000+v1+v2,当其中一条链已经加完后,直接把剩下的接在L链上

    g) 结果的符号与绝对值大的相同

    h) 相加时,如果一些结点的data归零了,则要删除,这一步需在完成所有相加运算后进行

    i) while语句控制输出

    DulNode.h
    
     
    
    #ifndef DULNODE_H
    #define DULNODE_H
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
     
    
    typedef struct DulNode{ //结点类型,双向链表
    int data;
    struct DulNode *prior;
    struct DulNode *next;
    }DulNode;
    
     
    
    void listCreate(DulNode *L,int n) /*创建链表*/
    {
    /*传入链表头结点,所需结点个数*/ 
    /*创建空链表*/
    int i;
    DulNode *p,*q;
    p=L;
    for(i=0;i!=n;i++) 
    {
    q=(DulNode*)malloc(sizeof(DulNode));
    p->next=q;
    q->prior=p; 
    p=q;
    }
    q->next = NULL; /*尾结点的next指向next*/
    }
    void destroyList(DulNode *L) /*销毁链表*/
    {
    /*传入头结点删除链表*/ 
    DulNode *p,*q;
    p=L;
    q=L;
    while(q!=NULL)
    {
    q=p->next;
    free(p);
    p=q;
    }
    } 
    int input(DulNode *L,char *s) /*输入*/
    {
    /*传入链表头结点和数字字符串*/
    /*先对字符串处理*/
    char *p,*ad;
    DulNode *q=NULL;
    int i,t,n,length,wei,data[20]; /*总长和位数(不含符号),data[]记录数据*/ 
    length=strlen(s);
    n=length/5;
    if(length%5!=0)
    n += 1; /*4位数为一组,有n组*/
    wei=length - n +1; /*不算逗号*/	
    listCreate(L,n); /*创建链表*/
    /*头结点data记录符号和位数*/ 
    L->data = wei; /*对正数的处理*/ 
    p=s; 
    if(s[0]=='-') /*对负数的处理*/
    { 
    wei -= 1;
    L->data = -1 * wei; 
    p=s+1; 
    } 
    /*开始将字符串变为数字*/
    for(i=0;i!=length;i++) /*改逗号分隔为终止符分隔*/
    {
    if(s[i]==',')
    s[i]='\0';
    }
    ad = p; 
    data[0]=atoi(ad);
    for(i=1;i!=n;i++) /*n为组数*/
    {
    for(;*ad!='\0';ad++);
    data[i]=atoi(++ad); /*记录每组数*/
    } 
    q=L->next;
    i=0;
    while(q!=NULL) /*总算存进去了*/
    {
    q->data = data[i];
    q=q->next;
    i++;
    } 
    return n; /*返回有效结点个数,即不包括头结点*/ 
    }
    
    void add(DulNode *L1,DulNode *L2,DulNode *L,DulNode *pad) /*相加并输出*/
    {
    /*要求L1的位数大于L2*/
    /*传入已经创建好并录入数据的两个加数链表的头结点*/
    /*和一个即将存储最终结果的链表的头结点*/
    int carry=0,borrow=0; /*进位和借位*/
    int m=0; /*记录组数*/ 
    DulNode *Lp1=L1,*Lp2=L2,*q=NULL; 
    /*从后面开始*/
    while(Lp1->next!=NULL)
    {
    Lp1=Lp1->next;
    m++;
    }
    while(Lp2->next!=NULL)
    Lp2=Lp2->next;
    /*完善结果链表*/
    listCreate(L,m+2);
    L->data=1; /*只把符号记下来*/
    if(L1->data < 0)
    L->data = -1; /*-1代表负号*/
    /*Lp1,Lp2都指向最后结点,开始相加*/
    q = L->next;
    
    if(L1->data * L2->data >= 0) /*同号直接相加*/
    {
    while(Lp1!=L1 && Lp2!=L2) 
    {
    q->data = Lp1->data + Lp2->data + carry;
    carry = q->data / 10000;
    q->data = q->data % 10000; /*进一*/ 
    q=q->next;
    Lp1=Lp1->prior;
    Lp2=Lp2->prior;
    }
    while(Lp1!=L1) /*已传入的L1位数更大规定*/
    {
    q->data = Lp1->data + carry;
    carry = q->data / 10000;
    q->data = q->data % 10000; /*进一*/ 
    q=q->next;
    Lp1=Lp1->prior;
    }
    if(carry != 0) 
    {
    q->data = carry;
    q=q->next;
    }
    }
    else if(L1->data * L2->data < 0) /*异号大数减小数*/
    {
    while(Lp1!=L1 && Lp2!=L2)
    {
    q->data = 10000 + Lp1->data - Lp2->data - borrow; 
    if(q->data / 10000 == 0)
    borrow = 1;
    else borrow = 0;
    q->data = q->data % 10000;
    q=q->next;
    Lp1=Lp1->prior;
    Lp2=Lp2->prior;
    }	
    while(Lp1 != L1)
    {
    q->data = Lp1->data - borrow;
    if(borrow != 0) 
    {
    q->data += 10000;
    if(q->data / 10000 == 0)
    borrow = 1;
    else borrow = 0;
    q->data = q->data % 10000;
    } 
    q=q->next;
    Lp1=Lp1->prior;
    }
    
    } 
    /*记录最终位置,方便从后往前输出*/
    pad = q->prior;	
    while(pad->data == 0 && pad->prior != L) 
    pad=pad->prior;
    
    printf("%d",L->data * pad->data);
    while(pad->prior != L)
    {
    pad=pad->prior;
    printf(",%04d",pad->data); //自动加0 
    /*	if(pad->prior != L)
    printf(",");*/
    }
    } 
    #endif
    
     
    
    测试:  main.h
    
    #include "Dulnode.h"
    
    int main()
    {
    DulNode *L1,*L2,*L,*pad;
    char s1[80],s2[80];
    
    int m,n;
    L1 = (DulNode*)malloc(sizeof(DulNode)); 
    L2 = (DulNode*)malloc(sizeof(DulNode)); 
    L = (DulNode*)malloc(sizeof(DulNode)); 
    printf("绝对值大的先输入:\n");
    gets(s1);
    gets(s2);
    m = input(L1,s1);
    n = input(L2,s2);
    
    /*返回有效结点个数,即不包括头结点*/ 
    add(L1,L2,L,pad);
    return 0;
    }
    

      感谢阅读!

  • 相关阅读:
    boost test学习(二)
    log4cxx的使用(2)
    Windows CE下流驱动的动态加载
    linux powerqorpp1010rdb 编译过程
    cadence allegro 设计重用
    Linux中VMware虚拟机硬盘空间扩大方法
    WINCE系统启动直接运行自己的程序
    linux6410触摸屏驱动
    cadence allegro和ad9之间的转换
    wince 6.0和5.0的区别
  • 原文地址:https://www.cnblogs.com/liulangbxc/p/11690969.html
Copyright © 2020-2023  润新知