#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
class Exchange {
public:
static int count; //静态数据变量为每个委托赋予独一无二的id
static bool match(const Exchange &a, const Exchange &b)
{
return a.price >= b.price;
}
int id;
int direction;
int volum;
int price;
int num;
Exchange(int d, int v, int p)
{
count++;
direction = d;
volum = v;//委托量
price = p;
id = count;
num = 0; //交易量
}
static int chaxun(int id, map<int, int> &unfinished, map<int, int> &finished);
};
int Exchange::chaxun(int id, map<int, int> &unfinished, map<int, int> &finished)
{
map<int, int>::iterator i=unfinished.find(id);
if (i != unfinished.end())
return i->second;
else i = finished.find(id);
if (i != finished.end())
return i->second;
else return -1;
}
int Exchange::count = 0;
struct cmp1 {
bool operator()(const Exchange &a, const Exchange &b)const
{
if (a.price == b.price)
return a.id < b.id;
else
return a.price < b.price;
}
};
struct cmp2 {
bool operator()(const Exchange &a, const Exchange &b) const
{
if (a.price == b.price)
return a.id > b.id;
else
return a.price < b.price;
}
};
void update(Exchange a, Exchange b, priority_queue<Exchange, vector<Exchange>, cmp1> &input, priority_queue<Exchange, vector<Exchange>, cmp2> &output, map<int, int> &unfinished)
{
input.pop(); output.pop(); //优先级队列的TOP元素为只读,修改内容需要先弹出,再修改,最后重新压入
int temp = min(a.volum, b.volum);
unfinished[a.id] = a.volum -= temp;
a.num += temp;
unfinished[b.id] = b.volum -= temp;
b.num += temp;
input.push(a); output.push(b);
}
char inputc()
{
char a;
cin >> a;
return a;
}
void exchange(priority_queue<Exchange, vector<Exchange>, cmp1> &input, priority_queue<Exchange, vector<Exchange>, cmp2> &output, map<int, int> &unfinished, map<int, int> &finished)
{
int d, v, p;
cin >> d >> v >> p;
if (d != 0 && d != 1)
{
cout << "\t您的委托类型输入有误,请重新输入:" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} //如果不清除缓存区,就有可能输出多条错误提示
if (d == 0)
{
priority_queue<Exchange, vector<Exchange>, cmp1>::value_type a(d, v, p);
input.push(a);
unfinished[a.id] = a.volum;
}
if (d == 1)
{
priority_queue<Exchange, vector<Exchange>, cmp2>::value_type a(d, v, p);
output.push(a);
unfinished[a.id] = a.num;
}
if (input.empty() || output.empty())
return;
while (!input.empty() && !output.empty())
{
if (Exchange::match(input.top(), output.top()))
{
Exchange p1(input.top());
Exchange p2(output.top());
update(p1, p2, input, output, unfinished);
if (input.top().volum == 0)
{
unfinished.erase(input.top().id); //如果委托量为零,则全部转入已交易的映射中
finished[input.top().id] = input.top().num;
input.pop();
}
if (output.top().volum == 0)
{
unfinished.erase(output.top().id);
finished[output.top().id] = output.top().num;
output.pop();
}
}
else
{
cout << "\n";
cout << "\t交易进行完成" << endl;//委托队列非空但不满足继续交易的条件
cout << "\n";
return;
}
}
cout << "\t交易进行完成" << endl; //有至少一方的委托队列为空,交易完成
}
int main()
{
priority_queue<Exchange, vector<Exchange>, cmp1>input;
priority_queue<Exchange, vector<Exchange>, cmp2>output;
map<int, int> finished; //用map存放已完成的交易信息,检索速度很快
map<int, int> unfinished; //用map存放未完成的交易信息
cout << "\t欢迎使用本交易系统"<<endl;
while (1)
{ cout << "\t 查询请按q\n\t 发出委托请按w\n\t 退出请按z"<<endl;
char temp = inputc();
if (temp == 'w')
{
cout << "\t确认发出委托请按y,返回上层请按n:"<<endl;
char t;
cin >> t;
if (t == 'y')
{
cout << "\t请输入委托类型,委托量,委托价格:"<<endl;
exchange(input, output, unfinished, finished);
}
else if (t == 'n')
continue;
else
{
cout << "\t您的输入有误,请重新输入:" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');//如果不清除缓存区,就有可能输出多条错误提示
continue;
}
}
else if (temp == 'q')
{
int id;
cout << "\t请输入委托单号:" << endl;
cin >> id;
if (Exchange::chaxun(id, unfinished, finished) != -1)
{
cout << "\n";
cout << "\t第" << id << "单委托的交易量为" << Exchange::chaxun(id, unfinished, finished) << endl;
cout << "\n";
}
else
cout << "\t并无此单,请重新输入" << endl;
}
else if (temp == 'z')
{
cout << "\t谢谢使用,再见!"<<endl;
break;
}
else
{
cout << "\t您的输入有误,请重新输入:" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
continue;
}
}
return 0;
}