[acm 1001] c++ 大数加法 乘法 幂
2015-04-12 10:09
435 查看
北大的ACM 1001
poj.org/problem?id=1001
代码纯手动编写 - -
poj.org/problem?id=1001
代码纯手动编写 - -
#include <iostream> #include <cstdio> #include <cstring> class BigNumber { struct BigNumberNode { BigNumberNode():n(0), prev(NULL), next(NULL){} BigNumberNode(int N):n(N), prev(NULL), next(NULL){} int n; BigNumberNode *prev, *next; }; BigNumberNode *head, *tail; int dot_before; // 小数点之前的数量 int dot_later; // 小数点之后的数量 void InsertNodeAtBegin(int n) { BigNumberNode *new_node = new BigNumberNode(n); if(head != NULL) { head->prev = new_node; new_node->prev = NULL; new_node->next = head; head = new_node; } else { head = new_node; tail = new_node; new_node->prev = NULL; new_node->next = NULL; } } void InsetNodeAtEnd(int n) { BigNumberNode *new_node = new BigNumberNode(n); if(head != NULL) { new_node->prev = tail; new_node->next = NULL; tail->next = new_node; tail = new_node; } else { head = new_node; tail = new_node; new_node->prev = NULL; new_node->next = NULL; } } void DeleteBegin() { if(head != NULL) { if (head->next != NULL) { BigNumberNode* temp = head->next; delete head; head = temp; temp->prev = NULL; if (dot_before != 0) { dot_before--; } else { dot_later--; } } else { Free(); } } } void DeleteEnd() { if(tail != NULL) { if (tail->prev != NULL) { BigNumberNode* temp = tail->prev; delete tail; tail = temp; temp->next = NULL; if (dot_later != 0) { dot_later--; } else { dot_before--; } } else { Free(); } } } // 去除前/后导 0 // 去除前/后导 0 void ClearZeros() { // 后导 0 BigNumberNode *p; int max_limit = dot_later; for(int i = 0; i < max_limit; i++) { p = tail; if(p->n == 0) { DeleteEnd(); } else { break; } } // 前导 0 max_limit = dot_before; for(int i = 0; i < max_limit; i++) { p = head; if(p->n == 0) { DeleteBegin(); } else { break; } } } BigNumber Mul(const BigNumber &Scale) { const BigNumber &a = *this, &b = Scale; BigNumber sum_big_number; int sum = 0; int reserve = 0; int tag = 0; BigNumberNode *pa = a.tail, *pb = b.tail; // xxxxxx a // xxx b // --------- Mul // xxxxxx // xxxxxx // xxxxxx // --------- Add // xxxxxxxxx while(pb) { BigNumber temp_big_number; pa = a.tail; while(pa) { sum = pa->n * pb->n + reserve; reserve = sum / 10; temp_big_number.InsertNodeAtBegin(sum - reserve * 10); temp_big_number.dot_before++; pa = pa->prev; } if (reserve) { temp_big_number.InsertNodeAtBegin(reserve); temp_big_number.dot_before++; reserve = 0; } for (int i = 0; i < tag; i++) { temp_big_number.InsetNodeAtEnd(0); temp_big_number.dot_before++; } sum_big_number += temp_big_number; tag++; pb = pb->prev; } sum_big_number.dot_later = a.dot_later + b.dot_later; if (sum_big_number.dot_before > sum_big_number.dot_later) { sum_big_number.dot_before -= sum_big_number.dot_later; } else { int temp = sum_big_number.dot_later - sum_big_number.dot_before; sum_big_number.dot_before = 0; for (int i = 0; i < temp; i++) { sum_big_number.InsertNodeAtBegin(0); } } sum_big_number.ClearZeros(); return sum_big_number; } public: ~BigNumber() { Free(); } BigNumber(): head(NULL), tail(NULL), dot_before(0), dot_later(0) { } BigNumber(const char *Str): head(NULL), tail(NULL), dot_before(0), dot_later(0) { Free(); AdaptFormString(Str); } BigNumber(const BigNumber& Source): head(NULL), tail(NULL), dot_before(0), dot_later(0) { *this = Source; } const BigNumber& operator=(const BigNumber& Source) { if (this != &Source) { this->Free(); BigNumberNode *p = Source.head; while(p) { this->InsetNodeAtEnd(p->n); p = p->next; } this->dot_before = Source.dot_before; this->dot_later = Source.dot_later; } return *this; } BigNumber operator+(const BigNumber Addend) { const BigNumber &a = *this, &b = Addend; BigNumber new_number; BigNumberNode *pa, *pb; int sum, remain, odd; int reserve = 0; bool is_dot_before_longer_is_a; // 帮助标记小数点之前的部分 bool is_dot_later_longer_is_a; // 小数点之后 if(a.dot_later > b.dot_later) { pa = a.tail; pb = b.tail; remain = b.dot_later; odd = a.dot_later - b.dot_later; is_dot_later_longer_is_a = true; } else { pa = b.tail; pb = a.tail; remain = a.dot_later; odd = b.dot_later - a.dot_later; is_dot_later_longer_is_a = false; } for (int i = 0; i < odd; i++) { new_number.InsertNodeAtBegin(pa->n); new_number.dot_later++; pa = pa->prev; } for (int i = 0; i < remain; i++) { sum = pa->n + pb->n + reserve; reserve = sum / 10; new_number.InsertNodeAtBegin(sum - reserve * 10); new_number.dot_later++; pa = pa->prev; pb = pb->prev; } // 小数点之前 if(a.dot_before > b.dot_before) { remain = b.dot_before; odd = a.dot_before - b.dot_before; is_dot_before_longer_is_a = true; } else { remain = a.dot_before; odd = b.dot_before - a.dot_before; is_dot_before_longer_is_a = false; } BigNumberNode *temp; // 用于交换 pa pb if (is_dot_before_longer_is_a && is_dot_later_longer_is_a || !is_dot_before_longer_is_a && !is_dot_later_longer_is_a) { // 不用交换 } else { temp = pa; pa = pb; pb = temp; } for (int i = 0; i < remain; i++) { sum = pa->n + pb->n + reserve; reserve = sum / 10; new_number.InsertNodeAtBegin(sum - reserve * 10); new_number.dot_before++; pa = pa->prev; pb = pb->prev; } for (int i = 0; i < odd; i++) { sum = pa->n + reserve; reserve = sum / 10; new_number.InsertNodeAtBegin(sum - reserve * 10); new_number.dot_before++; pa = pa->prev; } // 检测是否最后还有一位 if (reserve) { new_number.InsertNodeAtBegin(reserve); new_number.dot_before++; reserve = 0; } new_number.ClearZeros(); return new_number; } BigNumber operator*(const BigNumber& Scale) { return Mul(Scale); } BigNumber& operator+=(const BigNumber Addend) { BigNumber &a = *this; const BigNumber &b = Addend; BigNumberNode *pa = a.tail, *pb = b.tail; int sum = 0, remain = 0, odd = 0; int reserve = 0; // 小数点之后 if(a.dot_later > b.dot_later) { remain = b.dot_later; odd = a.dot_later - b.dot_later; for (int i = 0; i < odd; i++) { pa = pa->prev; } } else { remain = a.dot_later; odd = b.dot_later - a.dot_later; char *odd_n = new char[odd]; for (int i = 1; i <= odd; i++) { odd_n[odd - i] = pb->n; pb = pb->prev; } for (int i = 0; i < odd; i++) { a.InsetNodeAtEnd(odd_n[i]); a.dot_later++; } delete odd_n; } for (int i = 0; i < remain; i++) { sum = pa->n + pb->n + reserve; reserve = sum / 10; pa->n = sum - reserve * 10; pa = pa->prev; pb = pb->prev; } // 小数点之前 if(a.dot_before > b.dot_before) { remain = b.dot_before; odd = a.dot_before - b.dot_before; for (int i = 0; i < remain; i++) { sum = pa->n + pb->n + reserve; reserve = sum / 10; pa->n = sum - reserve * 10; pa = pa->prev; pb = pb->prev; } for (int i = 0; i < odd; i++) { sum = pa->n + reserve; reserve = sum / 10; pa->n = sum - reserve * 10; pa = pa->prev; } } else { remain = a.dot_before; odd = b.dot_before - a.dot_before; for (int i = 0; i < remain; i++) { sum = pa->n + pb->n + reserve; reserve = sum / 10; pa->n = sum - reserve * 10; pa = pa->prev; pb = pb->prev; } for (int i = 0; i < odd; i++) { sum = pb->n + reserve; reserve = sum / 10; a.InsertNodeAtBegin(sum - reserve * 10); a.dot_before++; pb = pb->prev; } } // 检测是否最后还有一位 if (reserve) { a.InsertNodeAtBegin(reserve); a.dot_before++; } a.ClearZeros(); return *this; } void _Print() { if(dot_before == 0 && dot_later == 0) { putchar('0'); } else if (dot_later == 0) { BigNumberNode *p = head; while(p) { putchar(p->n + '0'); p = p->next; } } else { BigNumberNode *p = head; for(int i = 0; i < dot_before; i++) { putchar(p->n + '0'); p = p->next; } putchar('.'); while(p) { putchar(p->n + '0'); p = p->next; } } } void PrintString() { if(dot_before == 0 && dot_later == 0) { putchar('0'); } else if (dot_later == 0) { char *temp = new char[dot_before + dot_later + 2], *ptemp = temp; BigNumberNode *p = head; while(p) { *ptemp = p->n + '0'; ptemp++; p = p->next; } *ptemp = 0; std::cout<<temp<<'\n'; delete[] temp; } else { char *temp = new char[dot_before + dot_later + 2], *ptemp = temp; BigNumberNode *p = head; for(int i = 0; i < dot_before; i++) { *ptemp = p->n + '0'; ptemp++; p = p->next; } *ptemp = '.'; ptemp++; while(p) { *ptemp = p->n + '0'; ptemp++; p = p->next; } *ptemp = 0; std::cout<<temp<<'\n'; delete[] temp; } } void Free() { BigNumberNode *p = head, *temp; while(p) { temp = p; p = p->next; delete temp; } head = NULL; tail = NULL; dot_before = 0; dot_later = 0; } // 从字符串建立数据,未加入错误检测 void AdaptFormString(const char *Str) { Free(); const char *pc = Str; // 小数点之前 while(*pc) { if(*pc != '.') // 0 ~ 9 { InsetNodeAtEnd(*pc - '0'); dot_before++; pc++; } else // 小数点之后 { pc++; while(*pc) { InsetNodeAtEnd(*pc - '0'); dot_later++; pc++; } break; } } ClearZeros(); } }; // 自顶向下的动态规划 BigNumber* BigNumberPowUP(BigNumber* result[], int pow) { if( result[pow] ) { return result[pow]; } else { int left = pow / 2; int right = pow - left; result[left] = BigNumberPowUP(result, left); result[right] = BigNumberPowUP(result, right); result[pow] = new BigNumber((*result[left]) * (*result[right])); return result[pow]; } } BigNumber BigNumberPow(const BigNumber& R, int pow) { BigNumber *result[26] = {0}; result[1] = new BigNumber(R); BigNumberPowUP(result, pow); BigNumber Result = *result[pow]; for (int i = 0; i <= pow; i++) { delete result[i]; } return Result; } int main(void) { char Rstr[10]; int n; while(scanf("%s%d", Rstr, &n) != EOF) { BigNumber result = BigNumberPow(Rstr, n); result.PrintString(); } return 0; }
相关文章推荐
- 大数运算之加法和乘法算法C++模板
- 整数大数模拟 高精度加法 高精度减法 高精度乘法 高精度除法 c/c++ java
- C++大数加法乘法
- vector、string实现大数加法乘法
- C++大作业之链表实现的高精度加法,减法,和数组实现的高精度乘法。
- 大数加法和大数乘法的实现
- 大数乘法C++实现
- 大数加法、乘法
- uva 465 - Overflow 大数加法 大数乘法
- C++ 大数乘法
- 大数加法和乘法
- nefu 120 Lucas-Lehmer 梅森素数判别法 二分-大数乘法换加法
- 多项式的加法与乘法(C++实现)
- nefu 120 Lucas-Lehmer 梅森素数判别法 二分-大数乘法换加法
- 大数加法 减法 乘法 除法 高精度四则运算
- 简单题POJ-1001,大数乘法
- 我用c++写的一个多项式的处理器的核心部分和输出部分。实现多项式的加法,减法,乘法,除法,及其求余。
- PKU ACM 1001(大数相乘)
- 基础算法,大数加法和乘法的实现
- nefu 120 Lucas-Lehmer 梅森素数判别法 二分-大数乘法换加法