結構體與鏈表進行任意長度數字相加Test

#include "stdafx.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

using namespace std;

//addNodePre and addNodeNex structure
struct Node
{
	int num;
	Node *pNode;
	Node *nNode;
};

//result structure
struct Result

{
	int num = 0;
	int carry = 0;
	Result *pNode;
	Result *nNode;
};

Result* getLastNode(Result* head)  //找到結果鏈表的尾部節點。傳入鏈表頭指針
{
	Result* wp;
	wp = head;
	while (wp->nNode != NULL)
	{
		wp = wp->nNode;
	}
	return wp;
}

Node* getLastNode(Node* head)  //找到加數鏈表的尾部節點。傳入鏈表頭指針
{
	Node* wp;
	wp = head;
	while (wp->nNode != NULL)
	{
		wp = wp->nNode;
	}
	return wp;
}

Node* insertNodeNum(int num, Node* head)  //在加數鏈表尾部添加一個節點,節點num爲加數
{
	Node *wp, *node;
	if (!(node = new Node))
	{
		cout << "allocate failed!";
		return NULL;
	}
	else{
		node->num = num;
		node->nNode = NULL;
		if (head == NULL)
		{
			head = node;
			return head;
		}
		wp = head;
		while (wp->nNode != NULL)
		{
			wp = wp->nNode;
		}
		wp->nNode = node;
		node->pNode = wp;
		return head;
	}
}

Result* insertResultNum(int num, Result* head)  //在結果鏈表尾部添加一個節點,節點num爲結果數
{
	Result *wp, *node;
	if (!(node = new Result))
	{
		cout << "allocate failed!";
		return NULL;
	}
	else{
		node->num = num;
		node->nNode = NULL;
		if (head == NULL)
		{
			head = node;
			return head;
		}
		wp = head;
		while (wp->nNode != NULL)
		{
			wp = wp->nNode;
		}
		wp->nNode = node;
		node->pNode = wp;
		return head;
	}
}

Result* addNodeNum(Node* addNodePre, Node* addNodeNex, Result* result) //加法
{                                                     
	Node* lastNodePre = getLastNode(addNodePre);// 加數
	Node* lastNodeNex = getLastNode(addNodeNex);// 被加數
	Result* resultNode = getLastNode(result);// 結果
	//下面計算加數長度的結果
	while (lastNodeNex != addNodeNex) // 若加數鏈表頭與鏈表尾部節點不相等,也就是加數鏈表中還有數據。
	{
		resultNode->num = lastNodePre->num + lastNodeNex->num + resultNode->carry;// 加數 被加數 和進位相加
		if (resultNode->num > 9)//結果若有進位
		{
			resultNode->num = resultNode->num % 10;
			resultNode->pNode->carry = 1;
		}
		lastNodePre = lastNodePre->pNode;//前移一位
		lastNodeNex = lastNodeNex->pNode;//前移一位
		resultNode = resultNode->pNode;//前移一位
	}

	resultNode->num = addNodeNex->num + lastNodePre->num + resultNode->carry; // 加數 被加數 和進位相加
	if (resultNode->num > 9)//結果若有進位         
	{
		resultNode->num = resultNode->num % 10;
		resultNode->pNode->carry = 1;
	}
	//下面算出被加數長度的結果
	while (lastNodePre != addNodePre)// 若被加數鏈表頭與鏈表尾部節點不相等,也就是被加數鏈表中還有數據。
	{
		lastNodePre = lastNodePre->pNode;//前移一位
		resultNode = resultNode->pNode;//前移一位
		resultNode->num = lastNodePre->num + resultNode->carry;//將進位與被加數相加
		if (resultNode->num > 9) 
		{
			resultNode->num = resultNode->num % 10;
			resultNode->pNode->carry = 1;
		}
	}
	resultNode = resultNode->pNode;//結果前移一位
	resultNode->num = resultNode->carry;
	return result;
}

Result* subNodeNum(Node* addNodePre, Node* addNodeNex, Result* result)//減法函數
{
	Node* lastNodePre = getLastNode(addNodePre);
	Node* lastNodeNex = getLastNode(addNodeNex);
	Result* resultNode = getLastNode(result);

	while (lastNodeNex != addNodeNex)
	{
		resultNode->num = lastNodePre->num - lastNodeNex->num + resultNode->carry;
		if (resultNode->num < 0) //若是有借位
		{
			resultNode->num += 10;
			resultNode->pNode->carry -= 1;
		}
		lastNodePre = lastNodePre->pNode;
		lastNodeNex = lastNodeNex->pNode;
		resultNode = resultNode->pNode;
	}

	resultNode->num = lastNodePre->num - addNodeNex->num + resultNode->carry;
	if (resultNode->num < 0) 
	{
		resultNode->num += 10;
		resultNode->pNode->carry -= 1;
	}

	while (lastNodePre != addNodePre)
	{
		lastNodePre = lastNodePre->pNode;
		resultNode = resultNode->pNode;
		resultNode->num = lastNodePre->num + resultNode->carry;
		if (resultNode->num < 0)
		{
			resultNode->num += 10;
			resultNode->pNode->carry -= 1;
		}
	}
	return result;
}

void resultNodeDis(Result* head)
{
	int srcPreLen[100];
	int i = 0;
	int flag = 0;
	Result* temp;
	Result* lastNode;
	Result* wp;

	memset(srcPreLen, 0, 100);
	lastNode = getLastNode(head);
	temp = head;
	while (temp)
	{
		if (temp->num == -1 || temp->num == 0)
		{
			if (temp == lastNode)
			{
				cout << "0";
			}
		}

		if (temp->num != -1 && temp->num != 0)
		{
			break;
		}
		temp = temp->nNode;
	}

	wp = head;
	while (wp)
	{
		if (wp->num != -1 && wp->num != 0 || flag == 1)
		{
			srcPreLen[i++] = wp->num;
			flag = 1;
		}
		wp = wp->nNode;
	}

	if (i > 4)
	{
		int k, w = i % 4;
		for (k = 0; k < w; k++)
		{
			cout << srcPreLen[k];
		}
		if (w != 0)
		{
			cout << ",";
		}
		for (; k < i; k++)
		{
			for (int d = 0; d < 4; d++)  
			{
				cout << srcPreLen[k];
				k++;
			}
			k--;
			if (k != i - 1)
			{
				cout << ",";
			}
		}
	}else
		{
			for (int g = 0; g < i; g++)
			{
				//cout << "輸出結果爲:";
				cout << srcPreLen[g];
			}
		}
}

int getInputStringLen(string s) // 計算所輸入字符串長度
{
	int cnt = 0;
	for (auto c : s)
	{
		if (isdigit(c))
		{
			++cnt;
		}
	}
	return cnt;
}


void moveToDest(string src, char* &dest, int n) // 將源字符串分拆爲字符串填入dest中
{
	int k = 1;

	if (isdigit(src[0]))
	{
		dest[0] = '1';
	}
	else 
		{
			dest[0] = '0';
		}

	for (int i = 0; k < n, i < src.length(); i++)
	{
		if (isdigit(src[i]))
		{
			dest[k] = src[i];
			k++;
		}
	}
}

int compareNeighborNode(string srcPrev, string srcNex) // 比較相鄰兩個字符串數據的大小
{

	int srcPreLen = getInputStringLen(srcPrev) + 1; 
	int srcNexLen = getInputStringLen(srcNex) + 1;
	if (srcPreLen > srcNexLen) 
	{
		return 1;
	}
	if (srcPreLen < srcNexLen) 
	{
		return 0;
	}
	char* destPrev = new char[srcPreLen];
	char* destNex = new char[srcNexLen];
	memset(destPrev, 0, srcPreLen);      
	memset(destNex, 0, srcNexLen);
	moveToDest(srcPrev, destPrev, srcPreLen);       
	moveToDest(srcNex, destNex, srcNexLen);

	for (int i = 1; i < srcPreLen; i++)
	{

		if (destPrev[i] > destNex[i])
		{
			return 1;
		}
		if (destPrev[i] < destNex[i])
		{
			return 0;
		}
	}
	return 1;
}

Node* chToIntAndInsert(Node* head, char* num, int n) // 將字符串轉換爲整數並插入到節點鏈表中
{
	for (int i = 1; i <= n - 1; i++)
	{
		int sum = num[i] - '0';
		head = insertNodeNum(sum, head);
	}
	return head;
}

int main(int argc, _TCHAR* argv[])
{
	//cout << endl;
	//cout << "請輸入第一個數:";
	Node* addNodePre = NULL;
	Node* addNodeNex = NULL;
	Result* result = NULL;
	string srcPrev, srcNex;
	char i;
	int srcPreLen = 0;
	int srcNexLen = 0;

	char* destPrev = NULL;
	char* destNex = NULL;
	cout << "所輸入字符串最大長度不能超過";
	cout << srcPrev.max_size();
	cout << endl;
	cout << "按任意非q鍵繼續,按q鍵退出!";
	cout << endl;
	while (_getch() != 'q')
	{
		addNodePre = NULL;
		addNodeNex = NULL;
		result = NULL;
		srcPreLen = 0;
		srcNexLen = 0;
		destPrev = NULL;
		destNex = NULL;
		i = '0';

		cout << "請輸入第一個數:";
		cin >> srcPrev; 
		for (auto c1 : srcPrev)
		{
			if (!isdigit(c1))
			{
				cout << "輸入的非數字字符,請重新輸入第一個數:";
				cin >> srcPrev; 
			}
		
		}
		cout << "請輸入第二個數:";
		cin >> srcNex;  
		for (auto c2 : srcNex)
		{
			if (!isdigit(c2))
			{
				cout << "輸入的非數字字符,請重新輸入第二個數:";
				cin >> srcNex; 
			}
		}
		cout << "最終輸出結果爲:";

		srcPreLen = getInputStringLen(srcPrev) + 1; //獲取輸入數據字符串的長度
		srcNexLen = getInputStringLen(srcNex) + 1; //獲取輸入數據字符串的長度
		destPrev = new char[srcPreLen];
		destNex = new char[srcNexLen];

		memset(destPrev, 0, srcPreLen);
		memset(destNex, 0, srcNexLen);
		moveToDest(srcPrev, destPrev, srcPreLen);
		moveToDest(srcNex, destNex, srcNexLen);

		addNodePre = chToIntAndInsert(addNodePre, destPrev, srcPreLen);
		addNodeNex = chToIntAndInsert(addNodeNex, destNex, srcNexLen);

		int q = srcPreLen > srcNexLen ? srcPreLen + 1 : srcNexLen + 1; //獲取兩個數長度較長的那個量
		for (int j = 1; j < q; j++)
		{
			result = insertResultNum(-1, result);
		}

		if (compareNeighborNode(srcPrev, srcNex))
		{
			if (destPrev[0] == '0' && destNex[0] == '0')
			{
				addNodeNum(addNodePre, addNodeNex, result);
				cout << "-";
				resultNodeDis(result);
			}

			if (destPrev[0] == '1' && destNex[0] == '0')
			{
				subNodeNum(addNodePre, addNodeNex, result);
				resultNodeDis(result);
			}

			if (destPrev[0] == '0'&& destNex[0] == '1')
			{
				subNodeNum(addNodePre, addNodeNex, result);
				cout << "-";
				resultNodeDis(result);
			}

			if (destPrev[0] == '1' && destNex[0] == '1')
			{
				addNodeNum(addNodePre, addNodeNex, result);
				resultNodeDis(result);
			}
		}
		else
			{
				if (destPrev[0] == '0' && destNex[0] == '0')
				{
					addNodeNum(addNodeNex, addNodePre, result);
					cout << "-";
					resultNodeDis(result);
				}

				if (destPrev[0] == '1' && destNex[0] == '0')
				{
					subNodeNum(addNodeNex, addNodePre, result);
					cout << "-";
					resultNodeDis(result);
				}

				if (destPrev[0] == '0' && destNex[0] == '1')
				{
					subNodeNum(addNodeNex, addNodePre, result);
					resultNodeDis(result);
				}

				if (destPrev[0] == '1' && destNex[0] == '1')
				{
					addNodeNum(addNodeNex, addNodePre, result);
					resultNodeDis(result);
				}
			}

		cout << endl;
		_getch();
		//cout << "按下q鍵退出!";
	}
	return 0;
}

 

結果:

數字字符太長會崩潰?需優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章