数据结构实验一 用链表实现大整数加减法

题目:

用链表实现大整数加减法操作:

32位机器直接操作的数据最大为32个bit,若超过32bit,则需要单独设计算法。在这里,可以用链表每个结点存储大整数的每一位的十进制数字,则可以进行大整数的算数运算,该实验仅实现加减法操作。

要求:

  1. 随机产生2个1~50位的数字串,并存储到2个链表中。
  2. 进行加法或减法操作,结果存储到新的链表中。
  3. 打印运算结果。

目录

BigInteger.h

BigInteger.cpp

function.h

function.cpp  

main.cpp

 


BigInteger.h

#include 
using namespace std;

struct Node {
    int data;
    Node* next;
};

class LinkList {
public:
    Node* front;
    int length = 0;//链表长度

    LinkList();//初始化
    ~LinkList();//释放内存
    void Insert(int);//插入数据
    void GetList();//调试用
    void PrintList();//打印
    int GetRear();//得到尾节点数据
};

BigInteger.cpp

#include "BigInteger.h"

//初始化链表
LinkList::LinkList() {
    front = new Node;
    front->next = NULL;
}

//释放动态内存
LinkList::~LinkList() {
    Node* p = front;
    while (p) {
        front = p;
        p = p->next;
        delete front;
    }
}

//头插法在链表插入数据
void LinkList::Insert(int x) {
    Node* s = new Node;
    s->data = x;
    s->next = front->next;
    front->next = s;
    length++;
}

//调试用函数(手动输入数据)
void LinkList::GetList() {
    char x;
    while (1) {
        x = getchar();
        if (x == '\n')   break;
        Insert(x - '0');
    }
}

//打印结果链表
void LinkList::PrintList() {
    Node* temp = front->next;
    if (temp->data == 0) temp = temp->next;
    while (temp != NULL) {
        cout << temp->data;
        temp = temp->next;
    }
    cout << endl;
}

//得到最高位数字大小在减法运算中进行比较
int LinkList::GetRear() {
    Node* temp = front->next;
    while (temp->next != NULL) temp = temp->next;
    return temp->data;
}

function.h

#include "BigInteger.h"

void Add(LinkList&, LinkList&, LinkList&);//大数相加

int Sub(LinkList&, LinkList&, LinkList&);//大数相减,返回1为正,0为负

void test();//测试函数

function.cpp 

#include "function.h"

//加法
void Add(LinkList& a, LinkList& b, LinkList& c) {
    int temp = 0, i = 0, al, bl;
    al = a.length;
    bl = b.length;
    Node* p = a.front->next, * q = b.front->next;
    for (; i < al && i < bl; i++) {
        int _data = p->data + q->data + temp;
        temp = _data / 10;//用temp进行是否进位操作
        c.Insert(_data % 10);
        p = p->next;
        q = q->next;
    }
    for (; i < al; i++) {
        int _data = p->data + temp;
        temp = _data / 10;
        c.Insert(_data % 10);
        p = p->next;
    }
    for (; i < bl; i++) {
        int _data = q->data + temp;
        temp = _data / 10;
        c.Insert(_data % 10);
        q = q->next;
    }
    if (temp) c.Insert(1);//temp等于1,最高位进1
}

//减法,根据返回值判断符号
int Sub(LinkList& a, LinkList& b, LinkList& c) {
    int temp = 0, flag = 0, i, al, bl;
    al = a.length;
    bl = b.length;
    Node* p = a.front->next, * q = b.front->next;
	if (al == bl) {
		if (a.GetRear() > b.GetRear()) {//被减数的最高位大于减数的最高位
			for (i = 0; i < al; i++) {//让大数1当作被减数
				if (p->data < q->data) {//借位操作
					p->data += 10;
					p->next->data--;
					temp = p->data - q->data;
					c.Insert(temp);
				}
				else {
					temp = p->data - q->data;
					c.Insert(temp);
				}
				p = p->next;
				q = q->next;
			}
			flag = 1;//结果为正
		}
		else {//被减数的最高位小于等于减数的最高位
			for (i = 0; i < al; i++) {//此时让大数2当作被减数,只不过最终要对结果加个负号
				if (q->data < p->data) {//进行减法运算不够向前借1
					q->data += 10;
					q->next->data--;
					temp = q->data - p->data;
					c.Insert(temp);
				}
				else {
					temp = q->data - p->data;
					c.Insert(temp);
				}
				p = p->next;
				q = q->next;
			}
			flag = 0;//结果为负
		}
	}
	else if (al > bl) {//被减数的位数大于减数
		for (i = 0; i < bl; i++) {//先处理两者的共同位
			if (p->data < q->data) {
				p->data += 10;
				p->next->data--;
				temp = p->data - q->data;
				c.Insert(temp);
			}
			else {
				temp = p->data - q->data;
				c.Insert(temp);
			}
			p = p->next;
			q = q->next;
		}
		for (; i < al; i++) {//把大数1多余的位加入结果
			if (p->data < 0) {//若借位时的高位为0,借位后高位为-1,需要进行再次借位
				p->data += 10;
				p->next->data--;
			}
			temp = p->data;
			c.Insert(temp);
			p = p->next;
		}
		flag = 1;//结果为正
	}
	else if (al < bl) {//被减数的位数小于减数,交换顺序,让大数2当作被减数,最终结果加负号
		for (i = 0; i < al; i++) {//此时先处理两者的共同位
			if (q->data < p->data) {
				q->data += 10;
				q->next->data--;
				temp = q->data - p->data;
				c.Insert(temp);
			}
			else {
				temp = q->data - p->data;
				c.Insert(temp);
			}
			p = p->next;
			q = q->next;
		}
		for (; i < bl; i++) {//把大数2多余的位加入结果
			if (q->data < 0) {//若借位时的高位为0,借位后高位为-1,需要进行再次借位
				q->data += 10;
				q->next->data--;
			}
			temp = q->data;
			c.Insert(temp);
			q = q->next;
		}
		flag = 0;//结果为负
	}
	return flag;
}

//测试
void test() {
    srand((unsigned)time(NULL));
    LinkList a, b, c, d;

    //随机a链
	cout << "The_first_rand_num:\n";
    int num = rand() % (50) + 1;//[1~50]
    int first = rand() % 10;//[0~9]
    while (first == 0) first = rand() % 10;//确保第一个数不为0
	a.Insert(first);
	cout << first;
	for (int i = 1; i < num; i++) {
		int temp = rand() % 10;
		cout << temp;
		a.Insert(temp);
	}cout << endl;

    //随机b链
	cout << "The_second_rand_num:\n";
    num = rand() % (50) + 1;//[1~50]
    first = rand() % 10;//[0~9]
    while (first == 0) first = rand() % 10;//确保第一个数不为0
	b.Insert(first);
	cout << first;
	for (int i = 1; i < num; i++) {
		int temp = rand() % 10;
		cout << temp;
		b.Insert(temp);
	}cout << endl;

    //加法
    cout << "Add to get:\n"; 
	Add(a, b, c);
	c.PrintList();
    
	//减法
    cout << "Subtract to get:\n";
	if (!Sub(a, b, d)) cout << "-";//根据返回值判断是否加负号
	d.PrintList();
	cout << endl;
}

main.cpp

#include "function.h"

int main() {
    int key;
    cout << "#TEST#\nEnter \"1\" to continue the test and enter \"0\" to end..." << endl << endl;
    while (cin >> key, key) {
        test();
    }
    system("pause");
    return 0;
}

你可能感兴趣的:(链表)