thoughtworks家庭作业C++版本

商品类:

#ifndef ITEM_H_
#define ITEM_H_

class SalesTax;

//This represents the Items which don't have an Import duty or any sales tax
class Item
{
public:

	//Constructors
	Item();
	Item (SalesTax *aSalesTax);

	//Interface Functions for Item

	//To calculate the price after tax and import duty
	virtual void CalculateTotalPrice();

	//To calculate the total tax and import duty
	virtual void CalculateTotalTax();

	//To set the price of the Items
	void SetPrice(double aPrice);

	//To set the number of the Items
	void SetNum(int aNum);

	//To set the message of the Items
	void SetMessage(char *src);

	//To get the message of the Items
	char* GetMessage();

	//To get the price of the Items before tax
	double getPrice();

	//To get the price of the items after tax
	double getTotalPrice();

	//To get the total tax and import duty of the items
	double getTax();

//Data
protected:
	//Works as the Strategy of the Sales Tax problem.
	//If in future the tax calculation becomes more complicated for different Items
	//we will just have to change this Strategy. We can also subclass this Strategy class
	//for future expansion of the tax calculation strategy
	SalesTax* iSalesTax;
//Data
protected:

	//These are the basic properties of any Item.
	//Hence these are made protected members so that the subclasses of Item can inherit
	//these properties
	int iNum;
	double iPrice;
	double iTotalPrice;
	double iTotalTax;
	//the information of the input
	char message[100];
};

//This class represents the Items which have only Import Duty
class ImportedItem : virtual public Item
{
public:
	//Constructors
	ImportedItem();

	//This constructor helps to create Items having only Import duty
	ImportedItem(SalesTax* aSalesTax, double aImportDuty);

	//Override
	virtual void CalculateTotalTax();

protected:
	double iImportDuty;
};

//This class represents the Items which have only Sales Tax but no Import Duty
class NonFoodBookMedicalItem : virtual public Item
{
public:
//Constructors
NonFoodBookMedicalItem();

//This constructor helps to create Items having only Sales tax
NonFoodBookMedicalItem(SalesTax* aSalesTax, double aRate);
//Override
virtual void CalculateTotalTax();

protected:
double iRate;
};

//This class represents the Items which have got both Import Duty as well as sales Tax
class NormalItem: public ImportedItem, public NonFoodBookMedicalItem
{
public:
NormalItem();
//This constructor helps to create Items having both Sales tax and Import duty
NormalItem(SalesTax* aSalesTax, double aRate, double aImportDuty);

//Override
virtual void CalculateTotalTax();
};

#endif /* ITEM_H_ */

#include "SalesTax.h"
#include "Item.h"

Item::Item(){}

Item::Item(SalesTax* aSalesTax):iSalesTax(aSalesTax),iPrice(0),iTotalPrice(0),iTotalTax(0){}

void Item::CalculateTotalPrice()
{
	iTotalPrice = iNum * iPrice + iTotalTax;
}

double Item::getTotalPrice()
{
	return iTotalPrice;
}


void Item::CalculateTotalTax()
{
	iTotalTax = iNum * iSalesTax->ComputeSalesTax(iPrice, 0, 0);
}

void Item::SetPrice(double aPrice)
{
	iPrice = aPrice;
}

void Item::SetNum(int aNum)
{
	iNum = aNum;
}

void Item::SetMessage(char *src)
{
	char *tmp = message;
	while((*tmp++ = *src++) != '\0');
}
char* Item::GetMessage()
{
	return message;
}

double Item::getPrice()
{
	return iPrice;
}

double Item::getTax()
{
	return iTotalTax;
}


ImportedItem::ImportedItem(){}

ImportedItem::ImportedItem(SalesTax* aSalesTax, double aImportDuty):Item(aSalesTax)
{
	iImportDuty = aImportDuty;
}
void ImportedItem::CalculateTotalTax()
{
	iTotalTax = iNum * iSalesTax->ComputeSalesTax(iPrice, 0, iImportDuty);
}


NonFoodBookMedicalItem::NonFoodBookMedicalItem(){}

NonFoodBookMedicalItem::NonFoodBookMedicalItem(SalesTax* aSalesTax, double aRate):Item(aSalesTax)
{
	iRate = aRate;
}

void NonFoodBookMedicalItem::CalculateTotalTax()
{
	iTotalTax = iNum * iSalesTax->ComputeSalesTax(iPrice, iRate, 0);
}


NormalItem::NormalItem() {}

NormalItem::NormalItem(SalesTax* aSalesTax, double aRate, double aImportDuty):Item(aSalesTax)
{
	iRate = aRate;
	iImportDuty = aImportDuty;
}
void NormalItem::CalculateTotalTax()
{
	iTotalTax = iNum * iSalesTax->ComputeSalesTax(iPrice, iRate, iImportDuty);
}

商品工厂

#ifndef ITEMCREATOR_H_
#define ITEMCREATOR_H_
#include "Item.h"

const int ITEM_WITH_NOSALESTAX_AND_IMPORTDUTY = 1;
const int ITEM_WITH_NOSALESTAX_ONLY_IMPORTDUTY = 2;
const int ITEM_WITH_ONLY_SALESTAX_AND_NOIMPORTDUTY = 3;
const int ITEM_WITH_BOTH_SALESTAX_AND_IMPORTDUTY = 4;

const double SALES_TAX_RATE = 10;
const double IMPORT_DUTY_RATE = 5;

class Not_A_Standard_Item_Type_Exception
{
	public:
	void printerrormsg();
};
class ItemCreator
{
	public:
	virtual Item* Create(int aItemId);
};

#endif /* ITEMCREATOR_H_ */

#include "ItemCreator.h"
#include "Item.h"
#include "SalesTax.h"

#include <iostream>

using namespace std;

void Not_A_Standard_Item_Type_Exception::printerrormsg()
{
	cout<<"Not the right Item Type..."<<endl;
}

Item* ItemCreator::Create(int aItemId)
{
	SalesTax* st = new SalesTax();

	switch(aItemId)
	{
		case ITEM_WITH_NOSALESTAX_AND_IMPORTDUTY:
		return new Item(st);
		break;

		case ITEM_WITH_NOSALESTAX_ONLY_IMPORTDUTY:
		return new ImportedItem(st,IMPORT_DUTY_RATE);
		break;

		case ITEM_WITH_ONLY_SALESTAX_AND_NOIMPORTDUTY:
		return new NonFoodBookMedicalItem(st,SALES_TAX_RATE);
		break;

		case ITEM_WITH_BOTH_SALESTAX_AND_IMPORTDUTY:
		return new NormalItem(st,SALES_TAX_RATE,IMPORT_DUTY_RATE);
		break;

		default:
		throw Not_A_Standard_Item_Type_Exception();
	}
}

税收政策:

#ifndef SALESTAX_H_
#define SALESTAX_H_
//This class works as the Strategy of the Sales tax problem
class SalesTax
{
public:

//Default constructor
SalesTax();

//This function helps to compute the Sales Tax
virtual double ComputeSalesTax(double aPrice, double aRate, double aImportduty);

private:
//This is an helper function which will round off the sales tax
double RoundOff(double aTax);
};

#endif /* SALESTAX_H_ */

#include "SalesTax.h"

SalesTax::SalesTax(){}

double SalesTax::ComputeSalesTax(double aPrice, double aRate, double aImportduty)
{
	double tx = aPrice * aRate / (double(100));
	double ty = aPrice * aImportduty / (double(100));

	double rtx = RoundOff(tx);
	double rty = RoundOff(ty);
	return rtx + rty;
}

double SalesTax::RoundOff(double aTax)
{
	double floor = 0.0;
	double ceil = 0.0;

	//获取整数
	int taxTemp = (int)aTax;
	//获取小数部分
	double decimaltaxTemp = (double)(aTax - (int)taxTemp);
	//获取第一位小数
	int tempy = (int)(1000 * decimaltaxTemp) / 100;
	//获取第二第三为小数
	int tempz = (int)(1000 * decimaltaxTemp - tempy  *100);
	//获取第二位小数
	int temp = (int)(tempz / 10);

	if(temp < 5)
	{
		floor = (double)taxTemp + (double)tempy * 0.1;
		ceil  = floor + 0.05;
	}
	else
	{
		floor = (double)taxTemp + (double)tempy * 0.1 + 0.05;
		ceil  = floor + 0.05;
	}

	return (aTax-floor) >= (ceil-aTax) ? ceil : floor;

}

main函数代码:

#include "SalesTax.h"
#include "Item.h"
#include "ItemCreator.h"

#include <iostream>
#include <iomanip>
#include <vector>
#include <stdlib.h>
#include <set>
#include <string>
#include <fstream>

using namespace std;

void decodeInfo(char *str, int &num, int &type, double &price);
void initNoBasicTaxLib();


//建立一个书本、食物、药品的库
set<string> noBasicTaxLib;


int main(int argc, char *argv[])
{
	//初始化字典库
	initNoBasicTaxLib();

	//输出文件的名字
	char output[20];
	
	//分割用到的变量
	char str[100];
	int iNum;
	int iType;
	double iPrice;

	typedef vector<Item*> listOfItem;
	listOfItem::iterator theIterator;

	listOfItem Basket;

	double totalprice = 0;
	double totaltax = 0;

	//产品制造工厂
	ItemCreator *itemCreator = new ItemCreator();

	for (int i = 1; i < argc; i++)
	{
		totalprice = 0;
		totaltax = 0;
		ifstream in;
		ofstream out;

		char * src = argv[i];
		char *p = output;

		//建立输出文档的名字
		while ((*p++ = *src++) != '\0');
		output[0] = 'o';
		output[1] = 'u';

		//打开文件
		in.open(argv[i], ios::in);
		if (!in.is_open())
		{
			exit(0);
		}
		out.open(output, ios::out);
		if (!out.is_open())
		{
			exit(0);
		}


		while (in.getline(str, 100))
		{	
			decodeInfo(str, iNum, iType, iPrice);

			try
			{
				Item* item = itemCreator->Create(iType);
				item->SetPrice(iPrice);
				item->SetMessage(str);
				item->SetNum(iNum);
				Basket.push_back(item);
			}
			catch(Not_A_Standard_Item_Type_Exception& e)
			{
				e.printerrormsg();
			}
		}//while

		//根据读取到的数据处理
		theIterator = Basket.begin();

		int pos = 0;
		while (theIterator != Basket.end())
		{
			Basket.at(pos)->CalculateTotalTax();
			totaltax += Basket.at(pos)->getTax();

			Basket.at(pos)->CalculateTotalPrice();
			double price = Basket.at(pos)->getPrice();
			double price_after_tax = Basket.at(pos)->getTotalPrice();
			totalprice += price_after_tax;

			out << Basket.at(pos)->GetMessage() << " " << fixed << setprecision(2) << price_after_tax << endl;
			theIterator++;
			pos++;
		}

		out<< "------------" << endl;
		out<< "Sales Tax: " << fixed << setprecision(2) << totaltax << endl;
		out<< "Total: " << totalprice << endl;

		Basket.clear();

		//关闭文件
		in.close();
		out.close();
	}//for

	system("pause");
	return 0;
}

//初始化药品库
void initNoBasicTaxLib()
{
	noBasicTaxLib.insert("pills");
	noBasicTaxLib.insert("chocolates");
	noBasicTaxLib.insert("book");
	noBasicTaxLib.insert("bar");
}

//分析字符串
void decodeInfo(char *str, int &num, int &type, double &price)
{
	bool imported_flag = false;
	bool basicTax_flag = true;

	const char *pImported = "imported";
	const char *pAt = "at";
	num = 0;
	char *pBegin = str;
	char *pEnd = pBegin;

	//得到商品的数量
	while (*pBegin == ' ')
	{
		++pBegin;
		++pEnd;
	}
	while (*pEnd != ' ')
	{
		num = num * 10 + (*pEnd - '0');
		++pEnd;
	}
	pBegin = pEnd;

	//获取商品是否为进口货

	//在整个字符串中找到at
	char *at_tag;
	while (*pBegin != '\0')
	{
		if(*pBegin == ' ')
		{
			++pBegin;
			++pEnd;
		}
		else if (*pEnd == ' ' || *pEnd == '\0')
		{
			if (pEnd - pBegin == 2 && strncmp(pBegin, pAt, 2) == 0)
			{
				at_tag = pBegin;
				break;
			}
			if(pEnd - pBegin == 8 && strncmp(pBegin, pImported, 8) == 0)
				imported_flag = true;

			pBegin = ++pEnd;
		}
		else
		{
			++pEnd;
		}
	}//while

	//定位了at之后,获取商品的类型和价格

	//类型
	--pBegin;
	while (*pBegin == ' ')
	{
		--pBegin;
	}
	char *pLast = pBegin;
	while(*pBegin != ' ')
	{
		--pBegin;
	}
	++pBegin;
	++pLast;
	string type_str(pBegin, pLast);
	if (noBasicTaxLib.find(type_str) != noBasicTaxLib.end())
	{
		basicTax_flag = false;
	}

	if(basicTax_flag == true && imported_flag == true)
	{
		type = 4;
	}
	else if (basicTax_flag == false && imported_flag == false)
	{
		type = 1;
	}
	else if (basicTax_flag = true && imported_flag == false)
	{
		type = 3;
	}
	else if (basicTax_flag == false && imported_flag == true)
	{
		type = 2;
	}
	else
	{}

	//价格
	while (*pEnd == ' ')
	{
		++pEnd;
	}
	price = atof(pEnd);

	//调整字符数组为输出格式
	*at_tag = ':';
	++at_tag;
	*at_tag = '\0';
}

  

posted @ 2015-10-29 18:02  stemon  阅读(957)  评论(0编辑  收藏  举报