银行作业分享,欢迎批评指正。到第12章。
下滑左侧有目录,点击可直达。
#pragma once #ifndef ARRAY_H #define ARRAY_H #include<cassert> template<class T> class Array { private: T* list; int size; public: Array(int sz = 50); Array(const Array<T>& a); ~Array(); Array<T>& operator=(const Array<T>& rhs); T& operator[](int i); const T& operator[](int i)const; operator T* (); operator const T* ()const; int getSize()const; void resize(int sz); }; template<class T> Array<T>::Array(int sz) { assert(sz >= 0); size = sz; list = new T[size]; } template<class T> Array<T>::~Array() { delete[]list; } template<class T> Array<T>::Array(const Array<T>& a) { size = a.size; list = new T[size]; for (int i = 0; i < size; i++) { list[i] = a.list[i]; } } template<class T> Array<T>& Array<T>::operator=(const Array<T>& rhs) { if (&rhs != this) { if (size != rhs.size) { delete[]list; size = rhs.szie; list = new T[size]; } for (int i = 0; i < size; i++) list[i] = rhs.list[i]; } return*this; } template<class T> T& Array<T>::operator[](int n) { assert(n >= 0 && n < size); return list[n]; } template<class T> const T& Array<T>::operator[](int n)const { assert(n >= 0 && n < size); return list[n]; } template<class T> Array<T>::operator T* () { return list; } template<class T> Array<T>::operator const T* ()const { return list; } template<class T> int Array<T>::getSize()const { return size; } template<class T> void Array<T>::resize(int sz) { assert(sz >= 0); if (sz == size)return; T* newList = new T[sz]; int n = (sz < size) ? sz : size; for (int i = 0; i < n; i++) newList[i] = list[i]; delete[]list; list = newList; size = sz; } #endif //ARRAY_H
#pragma once #ifndef _ACCUMULATOR_H_ #define _ACCUMULATOR_H_ #include"date.h" class Accumulator { private: Date lastDate; double value; double sum; public: Accumulator(const Date&date,double value):lastDate(date),value(value),sum(0){} double getSum(const Date& date)const { return sum + value * date.distance(lastDate); } void change(const Date& date, double value) { sum = getSum(date); lastDate = date; this->value = value; } void reset(const Date& date, double value) { lastDate = date; this->value = value; sum = 0; } }; #endif // !_ACCUMULATOR_H_
#pragma once #ifndef _DATE_H_ #define _DATE_H_ #include<iostream> class Date { private: int year; int month; int day; int totalDays; public: Date(int year=1, int month=1, int day=1); //static Date read(); int getYear()const { return year; } int getMonth()const { return month; } int getDay()const { return day; } int getMaxDay()const; bool isLeapYear()const { return year % 4 == 0 && year % 100 != 0 || year % 400 == 0; } void show()const; int distance(const Date& date)const { return totalDays - date.totalDays; } int operator-(const Date& date)const { return totalDays - date.totalDays; } bool operator<(const Date& date)const { return totalDays < date.totalDays; } }; std::istream& operator>>(std::istream& in, Date& date); std::ostream& operator<<(std::ostream& out, const Date& date); #endif // !_DATE_H_
#pragma once #ifndef _ACCOUNT_H_ #define _ACCOUNT_H_ #include"date.h" #include"accumulator.h" #include<string> #include<map> #include<istream> #include<stdexcept> using namespace std; class Account; class AccountRecord { private: Date date; const Account* account; double amount; double balance; std::string desc; public: AccountRecord(const Date& date, const Account* account, double amount, double balance, const std::string& desc); void show()const; }; typedef std::multimap<Date, AccountRecord>RecordMap; class Account { private: std::string id; double balance; static double total; static RecordMap recordMap; protected: Account(const Date& date, const std::string& id); void record(const Date& date, double amount, const std::string& desc); void error(const std::string& msg)const; public: const string& getId()const { return id; } double getBalance()const { return balance; } static double getTotal() { return total; } virtual void deposit(const Date& date, double amount, const std::string& desc ) = 0; virtual void withdraw(const Date& date, double amount, const std::string& desc ) = 0; virtual void settle(const Date& date) = 0; virtual void show( std::ostream &out)const; void show()const; static void query(const Date& begin, const Date& end); }; inline std::ostream& operator<<(std::ostream & out, const Account& account) { account.show(out); return out; } class SavingsAccount :public Account { private: double rate; Accumulator acc; public: SavingsAccount(const Date& date, const string& id, double rate); double getRate()const { return rate; } void deposit(const Date& date, double amount, const string& desc); void withdraw(const Date& date, double amount, const string& desc); void settle(const Date& date); }; class CreditAccount :public Account { private: Accumulator acc; double credit; double rate; double fee; double getDebt()const { double balance = getBalance(); return(balance < 0 ? balance : 0); } public: CreditAccount(const Date & date, const string & id, double credit, double rate, double fee); double getCredit()const { return credit; } double getRate()const { return rate; } double getFee()const { return fee; } double getAvailableCredit()const { if (getBalance() < 0)return credit + getBalance(); else return credit; } void deposit(const Date& date, double amount, const string& desc); void withdraw(const Date& date, double amount, const string& desc); void settle(const Date& date); virtual void show(std::ostream &out)const; }; class AccountException :public std::runtime_error { private: const Account* account; public: AccountException(const Account*account,const std::string&msg) :runtime_error(msg),account(account){} const Account* getAccount()const { return account; } }; #endif // !_ACCOUNT_H_
#include"account.h" #include<cmath> #include<iostream> #include<utility> using namespace std; using namespace std::rel_ops; double Account::total = 0; RecordMap Account::recordMap; AccountRecord::AccountRecord(const Date& date, const Account* account, double amount, double balance, const std::string& desc) :date(date), account(account), amount(amount), balance(balance), desc(desc) { date.show(); cout << "\t#" << account->getId() << "\t" << amount << "\t" << balance << "\t" << desc << endl; } void AccountRecord::show()const { cout << date << "\t#" << account->getId() << "\t" << amount << "\t" << balance << "\t" << desc << endl; } void Account::query(const Date& begin, const Date& end) { if (begin <= end) { RecordMap::iterator iter1 = recordMap.lower_bound(begin); RecordMap::iterator iter2 = recordMap.upper_bound(end); for (RecordMap::iterator iter = iter1; iter != iter2; ++iter) iter->second.show(); } } Account::Account(const Date& date, const string& id):id(id),balance(0) { cout <<date<< "\t# " << id << " created" << endl; } void Account::record(const Date& date, double amount, const string& desc) { AccountRecord* accountrecord; accountrecord = new AccountRecord(date, this, amount, this->getBalance(), desc); Account::recordMap.insert(make_pair(date, (*accountrecord))); amount = floor(amount * 100 + 0.5) / 100; balance += amount; total += amount; date.show(); cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl; } void Account::show(ostream&out)const { out << id << "\tBalance:" << balance; } void Account::show()const { cout << id << "\tBalance:" << balance; } void Account::error(const string& msg)const { throw AccountException(this, msg); } SavingsAccount::SavingsAccount(const Date&date,const string&id,double rate) :Account(date,id),rate(rate),acc(date,0){} void SavingsAccount::deposit(const Date& date, double amount, const string& desc) { record(date, amount, desc); acc.change(date, getBalance()); } void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) { if (amount > getBalance()) { error("not enough money"); } else { record(date, -amount, desc); acc.change(date, getBalance()); } } void SavingsAccount::settle(const Date& date) { if (date.getMonth() == 1) { double interest = acc.getSum(date) * rate / (date - Date(date.getYear() - 1, 1, 1)); if (interest != 0) record(date, interest, "interest"); acc.reset(date, getBalance()); } } CreditAccount::CreditAccount(const Date& date, const string& id, double credit, double rate, double fee) :Account(date,id),credit(credit),rate(rate),fee(fee),acc(date,0){} void CreditAccount::deposit(const Date& date, double amount, const string& desc) { record(date, amount, desc); acc.change(date, getDebt()); } void CreditAccount::withdraw(const Date& date, double amount, const string& desc) { if (amount - getBalance() > credit) { error("not enough creidt"); } else { record(date, -amount, desc); acc.change(date, getDebt()); } } void CreditAccount::settle(const Date& date) { double interest = acc.getSum(date) * rate; if (interest != 0)record(date, interest, "interest"); if (date.getMonth() == 1)record(date, -fee, "annual fee"); acc.reset(date, getDebt()); } void CreditAccount::show(ostream&out)const { Account::show(out); out << "\tAvailable credit:" << getAvailableCredit(); }
#include"date.h" #include<iostream> #include<cstdlib> #include<stdexcept> using namespace std; namespace { const int DAYS_BEFORE_MONTH[] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 }; } Date::Date(int year, int month, int day) :year(year), month(month), day(day) { if (day <= 0 || day > getMaxDay()) throw runtime_error("Invalid date"); int years = year - 1; totalDays = years * 365 + years / 4 - years / 100 + years / 400 + DAYS_BEFORE_MONTH[month - 1] + day; if (isLeapYear() && month > 2)totalDays++; } istream& operator>>(istream& in, Date& date) { int year, month, day; char c1, c2;; in >> year >> c1 >> month >> c2 >> day; if (c1 != '-' || c2 != '-')throw runtime_error("Bad time format"); date = Date(year, month, day); return in; } int Date::getMaxDay()const { if (isLeapYear() && month == 2)return 29; else return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1]; } void Date::show()const { cout << getYear() << "-" << getMonth() << "-" << getDay(); } ostream& operator<<(ostream& out, const Date& date) { out << date.getYear() << "-" << date.getMonth() << "-" << date.getDay(); return out; }
#include"account.h" #include<iostream> #include<fstream> #include<sstream> #include<vector> #include<algorithm> using namespace std; struct deleter { template<class T>void operator()(T* p) { delete p; } }; class Controller { private: Date date; vector<Account*>accounts; bool end; public: Controller(const Date&date):date(date),end(false){} ~Controller(); const Date& getDate()const { return date; } bool isEnd()const { return end; } bool runCommand(const string& cmdLine); }; Controller::~Controller() { for_each(accounts.begin(), accounts.end(), deleter()); } bool Controller::runCommand(const string& cmdLine) { istringstream str(cmdLine); char cmd, type; int index, day; double amount, credit, rate, fee; string id, desc; Account* account; Date date1, date2; str >> cmd; switch (cmd) { case 'a': str >> type >> id; if (type == 's') { str >> rate; account = new SavingsAccount(date, id, rate); } else { str >> credit >> rate >> fee; account = new CreditAccount(date, id, credit, rate, fee); } accounts.push_back(account); return true; case 'd': str >> index >> amount; getline(str, desc); accounts[index]->deposit(date, amount, desc); return true; case 'w': str>> index >> amount; getline(str, desc); accounts[index]->withdraw(date, amount, desc); return true; case 's': for (size_t i = 0; i < accounts.size(); i++) { cout << "[" << i << "]"; accounts[i]->show(); cout << endl; } return false; case 'c': str >> day; if (day < date.getDay())cout << "You cannot specify a previous day"; else if (day > date.getMaxDay())cout << "Invalid day"; else date = Date(date.getYear(), date.getMonth(), day); return true; case 'n': if (date.getMonth() == 12)date = Date(date.getYear() + 1, 1, 1); else date = Date(date.getYear(), date.getMonth() + 1, 1); for (vector<Account*>::iterator iter = accounts.begin(); iter != accounts.end(); ++iter) { (*iter)->settle(date); } return true; case 'q': str >> date1 >> date2; Account::query(date1, date2); return false; case 'e': end = true; return false; } cout << "Invalid command:" << cmdLine << endl; return false; } int main(void) { Date date(2008,11,1); Controller controller(date); string cmdLine; const char* FILE_NAME = "commands.txt"; ifstream fileIn(FILE_NAME); if (fileIn) { while (getline(fileIn, cmdLine)){ try { controller.runCommand(cmdLine); } catch (exception& e) { cout << "Bad line in " << FILE_NAME << ": " << cmdLine << endl; cout << "Error: " << e.what() << endl; return 1; } } fileIn.close(); } ofstream fileOut(FILE_NAME, ios_base::app); cout << "(a)add account (d)deposit (w)withdraw (s)show (c)change day (n)next month (q)query (e)exit" << endl; while (!controller.isEnd()) { cout << controller.getDate() << "\tTotal:" << Account::getTotal() << "\tcommand>"; string cmdLine; getline(cin, cmdLine); try { if (controller.runCommand(cmdLine))fileOut << cmdLine << endl; } catch (AccountException& e) { cout << "Error(#" << e.getAccount()->getId() << "):" << e.what() << endl; } catch (exception& e) { cout << "Error:" << e.what() << endl; } } return 0; }
a s 02342342 0.015 a c C5392394 10000 0.0005 50 a c C5392394 10000 0.0005 50 d 0 5000 salary c 15 w 2 2000 buy a cell c 25 d 1 10000 sell stock 0323 n d 2 2016 repay the credit c 5 d 0 5500 salary n w 2 20000 buy a car w 2 1500 buy a television q 2008-12-5 2009-1-32 q 2008-12-5 2009-1-31 e