中级农民
- 积分
- 103
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2016-9-30
- 最后登录
- 1970-1-1
|
按照楼上的讨论,附上解法,请指正
class BstTreeNode;
typedef std::shared_ptr<BstTreeNode> BstTreeNodePtr;
class BstTreeNode {
public:
BstTreeNode(float price, long quantity)
: m_price(price), m_quantity(quantity) {}
private:
friend class BstTree;
// double have much better precision than float, but in general stock price
// will only have
// less than 3 decimal digits.
float m_price;
// I would say long is good enough, its maximum value are just more than 2
// billion.
// You can switch to unsigned long if you want.
long m_quantity;
BstTreeNodePtr m_left, m_right;
};
class BstTree {
public:
BstTree() : m_root(new BstTreeNode(0, 0)) {}
void AddNode(float price, long quantity) {
BstTreeNodePtr curr(m_root), parent;
while (curr) {
parent = curr;
if (curr->m_price == price) {
curr->m_quantity += quantity;
return;
} else if (curr->m_price > price) {
curr = curr->m_left;
} else {
curr = curr->m_right;
}
}
if (parent->m_price > price)
parent->m_left = std::make_shared<BstTreeNode>(price, quantity);
else
parent->m_right = std::make_shared<BstTreeNode>(price, quantity);
}
float GetMinSellPrice() {
return m_root->m_right ? m_root->m_right->m_price : 0;
}
float GetMaxBuyPrice() {
BstTreeNodePtr curr(m_root);
while (curr->m_left) {
curr = curr->m_left;
}
return curr->m_price;
}
// Need use double here, total cost coulbe be more than 2 billion.
// Very rare, but can't rule out that possibility.
double GetTotalCost() {
BstTreeNodePtr curr(m_root->m_left);
if (!curr) return 0;
double reval(0);
std::stack<BstTreeNodePtr> my_stack;
my_stack.push(curr);
while (!my_stack.empty()) {
curr = my_stack.top();
reval += (curr->m_price * curr->m_quantity);
my_stack.pop();
if(curr->m_left)my_stack.push(curr->m_left);
if(curr->m_right)my_stack.push(curr->m_right);
}
return reval;
}
private:
BstTreeNodePtr m_root;
};
typedef std::shared_ptr<BstTree> BstTreePtr;
enum TradeType {
BUY,
SELL
};
class TradeBook {
public:
TradeBook() {}
void AddTrade(const std::string& symbol, const std::string& company,
float price, const long quantity, const TradeType& trade_type) {
if (m_company_price_mapper.count(company) == 0) {
m_company_price_mapper[company] = std::make_shared<BstTree>();
m_symbol_company_mapper[symbol] = company;
}
if (trade_type == BUY) price = -price;
m_company_price_mapper[company]->AddNode(price, quantity);
}
void Delete(const std::string& symbol) {
if (m_symbol_company_mapper.count(symbol) == 0) return;
const std::string company(m_symbol_company_mapper[symbol]);
m_company_price_mapper.erase(company);
m_symbol_company_mapper.erase(symbol);
}
float GetMinSellPrice(const std::string& company) {
if (m_company_price_mapper.count(company) == 0) return 0;
return m_company_price_mapper[company]->GetMinSellPrice();
}
float GetMaxBuyPrice(const std::string& company) {
if (m_company_price_mapper.count(company) == 0) return 0;
return - m_company_price_mapper[company]->GetMaxBuyPrice();
}
double GetTotalCost(const std::string & company) {
if (m_company_price_mapper.count(company) == 0) return 0;
return - m_company_price_mapper[company]->GetTotalCost();
}
private:
std::unordered_map<std::string, std::string> m_symbol_company_mapper;
std::unordered_map<std::string, BstTreePtr> m_company_price_mapper;
};
|
|