Method of Handling Factorials of Any Size

However, one method to get around this is to dynamically create a linked list such that each element
in the list represents a single digit of the result. That way, theorically speaking, the result’s length
is only limited by the memory!

Steps to Use

  1. Set up a dual_direction linked list,and allocate the first element which is 1 (I’m assuming straight C++.
    However, if you’re using MFC, you can also use an MFC collection class such as the CPtrList class.
    I personally prefer to create my own class for this purpose.
  2. From the first element to the nth element (last element),
    simply create an element in the list of each digit until you don’t have any more digits in the return result.

Code

//
//
// Nnn.cpp : Defines the entry point for the console application.
// author : Hai Yi
// date : Sept,11,2000
//
//

#include “stdafx.h”

#include “iostream.h”
#include “stdlib.h”

//here is a dual link list
class Node{

private:
int data;
Node *next;
Node *prev;
Node *head;
Node *rear;

public:
Node(const int& item)
:data(item),prev(NULL),next(NULL),head(NULL),rear(NULL){};

//get next node
Node* GetNextNode(){return next;};
Node* GetPrevNode(){return prev;};

//insert after
void InsertAfterMe(Node* p);

//Delete the appointed
void DeleteMe(void);

int GetData(void){return data;};
void SetData(int item){data = item;};

//reset
Node* GoBacktoHead();

//go to the rear
Node* GoForwardtoRear();
//clear the whole
void ClearAll(void);

//get the counts of the link
int GetElementNum();
};

int Node::GetElementNum()
{
int count = 0;
Node* p =GoBacktoHead();

while(p->GetNextNode()!=NULL){
count++;
p = p->GetNextNode();
}

count++;
return count;
}

void Node::InsertAfterMe(Node* p)
{
// Node* p;
if(prev == NULL) { head = this;}
p->next = next;
p->prev = this;
next = p;
if(p->next == NULL){rear = p;}
};

void Node::DeleteMe(void)
{
if(prev == NULL) { // if this node is the first one
next->prev = NULL;
head = next; // then the next one becomes the first one
delete this; //delete this node
return;
}

if(next == NULL){ //if this node is the last one
prev->next = NULL;
rear = prev; // then the previous one becomes the last one
return;
}

prev->next = next;
delete this;
};

Node* Node::GoBacktoHead()
{
if(head == this){ //this is the first node
return this;
}

Node *p = this;
while(p->prev != NULL){
p = p->prev;
}

return p;
}

Node* Node::GoForwardtoRear()
{
if(rear == this){
return this;
}

Node *p = this;
while(p->next != NULL){
p = p->next;
}

return p;
}

void Node::ClearAll(void)
{
Node* p = GoBacktoHead();
Node* p2;
while(p->GetNextNode() != NULL){
p2 = p;
p = p->GetNextNode();
delete p2;
}

delete p;
};

int main(int argc, char* argv[])
{
int remain;
int carry;
int result;
int N;
Node* p = new Node(1);

cout<<“Pls input the number:”;
cin>>N;
for(int n=1;n<=N;n++)
{
remain = carry = 0;
p = p->GoBacktoHead();

//while not the end of the list,process the element one by one
while(p->GetNextNode() != NULL){
result = p->GetData()*n+carry;
if(result>=10){
remain = result%10;
carry = result/10;
p->SetData(remain);
}
else{p->SetData(result);}

p = p->GetNextNode();
carry = result/10;
}

result = p->GetData()*n+carry;

//if carry occurs,process the carry and
//store into the newly allocated space.

while(result >= 10){
Node * newNode = new Node(0);
p->SetData(result%10);//remainder
result = result/10;
p->InsertAfterMe(newNode);
p = p->GetNextNode();
}

p->SetData(result);

}//end of if

p = p->GoForwardtoRear();

while(p->GetPrevNode()!=NULL){
cout<<p->GetData();
p=p->GetPrevNode();
}

cout<<p->GetData()<<endl;
int num = p->GetElementNum();
if(num >=5){
p = p->GoForwardtoRear();

cout<<endl<<“Or”<<endl<<endl;

cout<<p->GetData()<<“.”;
p = p->GetPrevNode();

for(int i=1;i<5;i++){
cout<<p->GetData();
p = p->GetPrevNode();
}

cout<<“E”<num-1<endl;
}

//clear the memory
p->ClearAll();

return 0;
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read