一个面试题。主要复习C++语法与STL和list sort 二元谓语函数编写。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<list>
using namespace std;
/*
authhor: ramanu_jan
*/
/**
* the Order class
*/
class Order{
public:
Order(){}
Order(string order_type, int price, int quantity, string order_id){
this->order_type = order_type; this->price = price;
this->quantity = quantity; this->order_id = order_id;
}
int get_price(){return price;}
int get_quantity(){return quantity;}
string get_order_id(){return order_id;}
string get_order_type(){return order_type;}
void set_price(int price){this->price = price;}
void set_quantity(int quantity){this->quantity = quantity;}
void set_order_id(string order_id){this->order_id = order_id;}
private:
string order_id;
string order_type;
int price;
int quantity;
};
/**
* use a buy list and a sell list to save orders for potential trades and PRINT operation.
* some string constants
*/
list<Order> l_buy, l_sell;
const string BUY("BUY"), SELL("SELL"), CANCEL("CANCEL"),
IOC("IOC"), GFD("GFD"), MODIFY("MODIFY"), PRINT("PRINT");
// buy operation
void buy(Order order){
list<Order>::iterator itr;
//check if IOC orders exists, and cancel it when exist.
for(itr = l_buy.begin(); itr != l_buy.end(); itr++)
if(itr->get_order_type() == IOC) l_buy.erase(itr);
//check the trade condition if exists, conducts the trade when exists.
for(itr = l_sell.begin(); itr != l_sell.end(); itr++){
if(order.get_price() >= itr->get_price()){ // trade occurs
int traded_quantity = min(itr->get_quantity(), order.get_quantity());
cout << "TRADE " << itr->get_order_id() << " " << itr->get_price() << " " << traded_quantity << " "
<< order.get_order_id() << " " << order.get_price() << " " << traded_quantity << endl;
if(order.get_quantity() >= itr->get_quantity()){
order.set_quantity(order.get_quantity() - itr->get_quantity());
l_sell.erase(itr);
}
else{
itr->set_quantity(itr->get_quantity() - order.get_quantity());
order.set_quantity(0); break;
}
}
}
//check if there is IOC type orders in sell queue, cancel them when there's.
for(itr = l_sell.begin(); itr !=l_sell.end(); itr++)
if(itr->get_order_type() == IOC) l_sell.erase(itr);
if(order.get_quantity() > 0) l_buy.push_back(order);
}
// sell operation
void sell(Order order){
list<Order>::iterator itr;
//check if IOC orders exists, and cancel it when exist.
for(itr = l_sell.begin(); itr != l_sell.end(); itr++)
if(itr->get_order_type() == IOC) l_sell.erase(itr);
//check the trade condition if exists, conducts the trade when exists.
for(itr = l_buy.begin(); itr !=l_buy.end(); itr++){
if(itr->get_price() >= order.get_price()){
int traded_quantity = min(itr->get_quantity(), order.get_quantity());
cout << "TRADE " << itr->get_order_id() << " " << itr->get_price() << " " << traded_quantity << " "
<< order.get_order_id() << " " << order.get_price() << " " << traded_quantity << endl;
if(order.get_quantity() >= itr->get_quantity()){
order.set_quantity(order.get_quantity() - itr->get_quantity());
l_buy.erase(itr);
}
else{
itr->set_quantity(itr->get_quantity() - order.get_quantity());
order.set_quantity(0); break;
}
}
}
//check if there is IOC type orders in buy queue, cancel them when there's.
for(itr = l_buy.begin(); itr != l_buy.end(); itr++)
if(itr->get_order_type() == IOC) l_buy.erase(itr);
if(order.get_quantity() > 0) l_sell.push_back(order);
}
// sell operation: check the input order id if exists in list sell and buy, cancel that when exists.
void cancel(string order_id){
list<Order>::iterator itr;
for(itr = l_buy.begin(); itr != l_buy.end(); itr++)
if(order_id == itr->get_order_id()){
l_buy.erase(itr); break;
}
for(itr = l_sell.begin(); itr != l_sell.end(); itr++)
if(order_id == itr->get_order_id()){
l_sell.erase(itr); break;
}
}
//modify operation
void modify(string order_id, string todo, int price, int quantity){
list<Order>::iterator itr;
//check if IOC orders exists, cancel them if exists.
for(itr = l_sell.begin(); itr != l_sell.end(); itr++) if(itr->get_order_type() == IOC)
l_sell.erase(itr);
for(itr = l_buy.begin(); itr != l_buy.end(); itr++) if(itr->get_order_type() == IOC)
l_buy.erase(itr);
//check sell orders
for(itr = l_sell.begin(); itr != l_sell.end(); itr++) if(itr->get_order_id() == order_id){
//when nothing modified, we just do nothing
//in other cases, we shall check if there is a trade.
if(todo == SELL && price == itr->get_price() && quantity == itr->get_quantity()) return;
Order order(itr->get_order_type(), price, quantity, order_id);
l_sell.erase(itr);
if(todo == SELL) sell(order);
else buy(order);
return;
}
//check buy orders
for(itr = l_buy.begin(); itr != l_sell.end(); itr++) if(itr->get_order_id() == order_id){
if(todo == BUY && price == itr->get_price() && quantity == itr->get_quantity()) return;
Order order(itr->get_order_type(), price, quantity, order_id);
l_buy.erase(itr);
if(todo == BUY) buy(order);
else sell(order);
return;
}
}
bool cmp(Order x, Order y){
return x.get_price() > y.get_price();
}
/**
* use backup lists to sort and integrate orders by price and different lists they are in, then print them out.
*/
void print(){
list<Order> lbuy(l_buy), lsell(l_sell);
lbuy.sort(cmp); lsell.sort(cmp);
if(lbuy.size() > 1){
list<Order>::iterator pre = lbuy.begin(), cur = pre; cur++;
while(cur != lbuy.end()){
if(cur->get_price() == pre->get_price()){
cur->set_quantity(cur->get_quantity() + pre->get_quantity());
lbuy.erase(pre);
pre = cur;
}
cur++;
}
}
if(lsell.size() > 1){
list<Order>::iterator pre = lsell.begin(), cur = pre; cur++;
while(cur != lsell.end()){
if(cur->get_price() == pre->get_price()){
cur->set_quantity(cur->get_quantity() + pre->get_quantity());
lsell.erase(pre);
pre = cur;
}
cur++;
}
}
list<Order>::iterator itr;
cout << "SELL:" << endl;
for(itr = lsell.begin(); itr != lsell.end(); itr++)
cout << itr->get_price() << " " << itr->get_quantity() << endl;
cout << "BUY:" << endl;
for(itr = lbuy.begin(); itr != lbuy.end(); itr++)
cout << itr->get_price() << " " << itr->get_quantity() << endl;
}
int main(){
l_buy.clear(); l_sell.clear();
string str;
while(cin >> str){
if(str == BUY){
string order_type, order_id; int price, quantity;
cin >> order_type >> price >> quantity >> order_id;
Order order(order_type, price, quantity, order_id);
buy(order);
}
else if(str == SELL){
string order_type, order_id; int price, quantity;
cin >> order_type >> price >> quantity >> order_id;
Order order(order_type, price, quantity, order_id);
sell(order);
}
else if(str == CANCEL){
string order_id;
cin >> order_id;
cancel(order_id);
}
else if(str == MODIFY){
string order_id, todo; int quantity, price;
cin >> order_id >> todo >> price >> quantity;
modify(order_id,todo, price, quantity);
}
else print();
}
return 0;
}