Files
159201/assignment4/as4/assignment04_159201_final_version.cpp
mooophy 686eed2091 all done, waiting for submission
renamed:    ../as4/main.cpp -> ../as4/assignment04_159201_final_version.cpp
2014-12-12 16:32:42 +13:00

156 lines
3.1 KiB
C++

//!
//! @author Wang Weixu 13114633
//! @date 12.12.2014
//!
//! @brief This code implemented Big Number using linked list as underlying
//! data structure.
//!
//! Assignment 4, 159.201,s3,2014
//!
#include <iostream>
#include <fstream>
#include <string>
namespace ads {
/**
* @brief Section A : The List class
*/
template<typename T>
class List
{
struct Node{ T value_; Node* prev_; Node* next_; };
public:
using SizeType = std::size_t;
void push_front(T const& new_value)
{
if(empty())
{
head_ = tail_ = new Node{new_value, nullptr, nullptr};
}
else
{
head_ = new Node{new_value, nullptr, head_};
head_->next_->prev_ = head_;
}
++size_;
}
bool empty()const
{
return !head_ and !tail_;
}
SizeType size() const
{
return size_;
}
~List()
{
if(not empty())
for(Node* ptr = head_, *tmp; (tmp=ptr); ptr=ptr->next_) delete tmp;
head_ = tail_ = nullptr;
}
protected:
Node* head_{};
Node* tail_{};
private:
SizeType size_{0};
};
template<typename T>
struct BigNumber;
template<typename T>
BigNumber<T> operator+(BigNumber<T> const& lhs, BigNumber<T> const& rhs);
/**
* @brief Section B : The BigNumber struct
*/
template<typename T>
struct BigNumber : private List<T>
{
friend BigNumber operator+ <T>(BigNumber const&, BigNumber const&);
using List<T>::push_front;
BigNumber() = default;
explicit BigNumber(std::string const& num)
{
for(auto c = num.crbegin(); c != num.crend(); ++c)
if(std::isdigit(*c)) push_front(*c - 48);
}
std::ostream& print() const
{
for(auto ptr = this->head_; ptr; ptr = ptr->next_) std::cout << ptr->value_;
return std::cout << std::endl;
}
};
/**
* @brief Section C : operator +
* @param lhs
* @param rhs
* @return the sum
*/
template<typename T>
BigNumber<T> operator+(BigNumber<T> const& lhs, BigNumber<T> const& rhs)
{
BigNumber<T> sum;
int carry = 0;
auto l = lhs.tail_, r = rhs.tail_;
for(; l and r; l = l->prev_, r = r->prev_) //add two numbers.
{
auto digit_sum = carry + l->value_ + r->value_ ;
sum.push_front(digit_sum%10);
carry = digit_sum/10;
}
for(auto rest = l?l:r; rest; rest = rest->prev_) //when either one exhausted.
{
auto digit_sum = carry + rest->value_;
sum.push_front(digit_sum%10);
carry = digit_sum/10;
}
if(carry) //for the last carry,if any.
sum.push_front(carry);
return sum;
}
}//namespace
int main(int argc, char ** argv)
{
if(argc!=2)
{
std::cout<< "cannot read the file " << argv[1] << std::endl;
exit(0);
}
std::string l,r;
{
std::ifstream ifs{argv[1]};
std::getline(ifs,l);
std::getline(ifs,r);
}
ads::BigNumber<int> lhs{l}, rhs{r};
lhs.print() << "+\n";
rhs.print() << "=\n";
(lhs+rhs).print();
return 0;
}