Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <iterator>
- #include <fstream>
- #include <sstream>
- #include <vector>
- class CIntN {
- protected:
- std::string filename;
- std::vector<int> nums;
- class Adder {
- int carry;
- public:
- Adder(): carry(0) {}
- int operator()(int x, int y) {
- int oldcarry = carry;
- carry = (x + y + oldcarry) / 10;
- return (x + y + oldcarry) % 10;
- }
- };
- class Invertor {
- public:
- int operator()(int x) {
- return 9 - x;
- }
- };
- public:
- virtual int output(const char* FileName = NULL) = 0;
- virtual CIntN& with(const char* str = NULL);
- virtual CIntN& operator=(const CIntN&);
- virtual CIntN* operator-() const = 0;
- virtual CIntN& operator+=(const CIntN&);
- virtual CIntN& operator-=(const CIntN&);
- virtual CIntN& negate();
- virtual ~CIntN() {
- };
- };
- CIntN& CIntN::with(const char *str) {
- std::stringstream ss((std::string(str)));
- int num;
- ss >> num;
- ss >> filename;
- int n;
- ss >> n;
- nums = std::vector<int>(n + 1, 0);
- std::string number;
- ss >> number;
- std::string::reverse_iterator end = number.rend();
- std::vector<int>::reverse_iterator vit = nums.rbegin();
- if (number[0] == '-' || number[0] == '+') --end;
- for (std::string::reverse_iterator it = number.rbegin(); it != end
- && vit != nums.rend(); ++it, ++vit) {
- *vit = *it - '0';
- }
- if (number[0] == '-') {
- negate();
- }
- return *this;
- }
- CIntN& CIntN::negate() {
- std::transform(nums.begin(), nums.end(), nums.begin(), Invertor());
- int carry = (*(nums.rbegin()) + 1) / 10;
- *(nums.rbegin()) = (*(nums.rbegin()) + 1) % 10;
- std::vector<int>::reverse_iterator it = nums.rbegin() + 1;
- for (; it < nums.rend(); ++it) {
- int oldcarry = carry;
- carry = (*it + oldcarry) / 10;
- *it = (*it + oldcarry) % 10;
- }
- return *this;
- }
- CIntN& CIntN::operator=(const CIntN& other) {
- nums.clear();
- std::copy(other.nums.begin(), other.nums.end(), std::back_inserter(nums));
- return *this;
- }
- CIntN& CIntN::operator+=(const CIntN& other) {
- if (nums.size() != other.nums.size()) {
- std::cerr << "Attempt to add CIntN's with different sizes!" << std::endl;
- }
- std::transform(nums.rbegin(), nums.rend(), other.nums.rbegin(), nums.rbegin(), Adder());
- return *this;
- }
- CIntN& CIntN::operator-=(const CIntN& other) {
- CIntN *tmp = -other;
- *this += *tmp;
- delete tmp;
- return *this;
- }
- class CIntN0: public CIntN {
- public:
- CIntN0() {
- nums = std::vector<int>();
- }
- CIntN0(const CIntN0& n0) {
- nums = std::vector<int>(n0.nums);
- }
- int output(const char* FileName = NULL) {
- std::ofstream of;
- if (FileName) {
- of.open(FileName);
- } else {
- of.open(filename.c_str());
- }
- of << nums.size() - 1 << " ";
- std::vector<int>::iterator it = nums.begin();
- if (nums[0] >= 5) {
- of << '-';
- negate();
- }
- while (*it == 0 && it != nums.end()) ++it;
- if (it == nums.end()) {
- of << 0;
- } else {
- std::copy(it, nums.end(), std::ostream_iterator<int>(of, ""));
- }
- of << std::endl;
- of.close();
- return 0;
- }
- CIntN* operator-() const {
- CIntN0 *ci = new CIntN0(*this);
- ci->negate();
- return ci;
- }
- ~CIntN0() {
- }
- };
- CIntN0 operator+(const CIntN0 &first, const CIntN0 &second) {
- CIntN0 res(first);
- res += second;
- return res;
- }
- CIntN0 operator-(const CIntN0 &first, const CIntN0 &second) {
- CIntN0 res(first);
- res -= second;
- return res;
- }
- class CIntN1: public CIntN {
- public:
- CIntN1() {
- nums = std::vector<int>();
- }
- CIntN1(const CIntN1& n1) {
- nums = std::vector<int>(n1.nums);
- }
- int output(const char* FileName = NULL) {
- std::ofstream of;
- if (FileName) {
- of.open(FileName);
- } else {
- of.open(filename.c_str());
- }
- of << nums.size() - 1 << std::endl;
- std::vector<int>::iterator it = nums.begin();
- if (nums[0] >= 5) {
- of << '-';
- negate();
- }
- while (*it == 0 && it != nums.end()) ++it;
- if (it == nums.end()) {
- of << 0;
- } else {
- std::copy(it, nums.end(), std::ostream_iterator<int>(of, ""));
- }
- of << std::endl;
- of.close();
- return 0;
- }
- CIntN* operator-() const {
- CIntN1 *ci = new CIntN1(*this);
- ci->negate();
- return ci;
- }
- ~CIntN1() {
- }
- };
- CIntN1 operator+(const CIntN1 &first, const CIntN1 &second) {
- CIntN1 res(first);
- res += second;
- return res;
- }
- CIntN1 operator-(const CIntN1 &first, const CIntN1 &second) {
- CIntN1 res(first);
- res -= second;
- return res;
- }
- class CIntNFactory {
- int i;
- public:
- CIntNFactory(int i): i(i) {};
- CIntN *createCIntN(const char* str);
- ~CIntNFactory() {
- }
- };
- CIntN *CIntNFactory::createCIntN(const char *str) {
- CIntN *ci;
- if (i == 0) {
- ci = new CIntN0();
- } else if (i == 1) {
- ci = new CIntN1();
- } else return NULL;
- ci->with(str);
- return ci;
- }
- CIntN *CreateCIntN(const char *str, CIntNFactory** factories) {
- return factories[str[0] - '0']->createCIntN(str);
- }
- int main() {
- std::string str;
- CIntNFactory **factories = new CIntNFactory*[2];
- factories[0] = new CIntNFactory(0);
- factories[1] = new CIntNFactory(1);
- std::ifstream in("input.txt");
- std::vector<CIntN*> arr;
- while (std::getline(in, str)) {
- arr.push_back(CreateCIntN(str.c_str(), factories));
- }
- CIntN *tmp = -(*(dynamic_cast<CIntN0*>(arr[0])));
- tmp->output("output6.txt");
- delete tmp;
- (*(dynamic_cast<CIntN1*>(arr[1])) + *(dynamic_cast<CIntN1*>(arr[3]))).output("output5.txt");
- for (std::vector<CIntN*>::iterator it = arr.begin(); it != arr.end(); ++it) {
- (*it)->output();
- delete *it;
- }
- delete factories[0];
- delete factories[1];
- delete[] factories;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement