Step3:增加TradeId区别确定各个挂单的唯一性,增加买卖股票的数量参数,并改进匹配算法
-module(stock).
-export([start/0,buy/1,sell/1]).
start()->
register(stock,spawn(fun()->loop([],[],1)end)).
buy(Trade) ->
stock!{buy,self(),Trade},
receive
{Pid,Response,Sell}->
{Response,Sell}
end.
sell(Trade) ->
stock!{sell,self(),Trade},
receive
{Pid,Response,Buy}->
{Response,Buy}
end.
loop(BuyL,SellL,TradeId)->
receive
{buy,Pid,{Price,Number,Name}}->
case lookup(sell,{Price,none},SellL) of
{_,Price,0,none}->
Pid!{self(),hangup,waiting},
L2=add(buy,{TradeId,Price,Number,Name},BuyL),
loop(L2,SellL,TradeId+1);
{TradeId1,Price1,Number1,Sell}->
Pid!{self(),ok,Sell},
if Number1=:=Number->
L2=remove({TradeId1,Price1,Number1,Sell},SellL),
loop(BuyL,L2,TradeId);
Number1<Number->
L2=remove({TradeId1,Price1,Number1,Sell},SellL),
self()!{buy,Pid,{Price,Number-Number1,Name}},
loop(BuyL,L2,TradeId);
Number1>Number->
L2=[replace(X,{TradeId1,Price1,Number1,Sell},Number1-Number)||X<-SellL],
loop(BuyL,L2,TradeId)
end
end;
{sell,Pid,{Price,Number,Name}}->
case lookup(buy,{Price,none},BuyL) of
{_,Price,0,none}->
Pid!{self(),hangup,waiting},
L2=add(sell,{TradeId,Price,Number,Name},SellL),
loop(BuyL,L2,TradeId+1);
{TradeId1,Price1,Number1,Buy}->
Pid!{self(),ok,Buy},
if Number1=:=Number->
L2=remove({TradeId1,Price1,Number1,Buy},BuyL),
loop(L2,SellL,TradeId);
Number1<Number->
L2=remove({TradeId1,Price1,Number1,Buy},BuyL),
self()!{sell,Pid,{Price,Number-Number1,Name}},
loop(L2,SellL,TradeId);
Number1>Number->
L2=[replace(X,{TradeId1,Price1,Number1,Buy},Number1-Number)||X<-BuyL],
loop(L2,SellL,TradeId)
end
end
end.
lookup(sell,{Price,Buy},[{TradeId,Price1,Number,Name}|_T]) ->
if
Price>=Price1 -> {TradeId,Price1,Number,Name};
true->{0,Price,0,Buy}
end;
lookup(buy,{Price,Sell},[{TradeId,Price1,Number,Name}|_T]) ->
if
Price=<Price1 -> {TradeId,Price1,Number,Name};
true->{0,Price,0,Sell}
end;
lookup(_,{Price,Name},[])->{0,Price,0,Name}.
add(sell,{TradeId,Price,Number,Name},[{TradeId1,Price1,Number1,Name1}|T]) ->
if
Price>=Price1 -> [{TradeId1,Price1,Number1,Name1}|add(sell,{TradeId,Price,Number,Name},T)];
true->[{TradeId,Price,Number,Name}|[{TradeId1,Price1,Number1,Name1}|T]]
end;
add(buy,{TradeId,Price,Number,Name},[{TradeId1,Price1,Number1,Name1}|T]) ->
if
Price=<Price1 -> [{TradeId1,Price1,Number1,Name1}|add(buy,{TradeId,Price,Number,Name},T)];
true->[{TradeId,Price,Number,Name}|[{TradeId1,Price1,Number1,Name1}|T]]
end;
add(_,{TradeId,Price,Number,Name},[])->[{TradeId,Price,Number,Name}].
remove(Trade,L)-> [X||X<-L,X/=Trade].
replace({TradeId,Price,Number,Name},{TradeId1,Price1,Number1,Name1},Number2)->
if
{TradeId1,Price1,Number1,Name1}=:={TradeId,Price,Number,Name}->
{TradeId,Price,Number2,Name};
true->{TradeId,Price,Number,Name}
end.