股票撮合系统

在股票交易中,股民可以通过各种手段将委托送到股票交易所。每个委托主要说明了股民身份、买卖的股票、价格和数量。交易的规则是价格优先、时间优先,即出的价格最高的人先买,出的价格最低的人先卖。两个委托只有价格合适时才能成交,未成交的委托按价格顺序放在撮合队列中。每个股票有两个撮合队列:买队列和卖队列。只有当买委托的价格高于等于卖委托的价格,两个委托才可以成交,成交价取两个委托价格的平均值,成交量取两个委托数量的最小值。委托可以是完全成交或部分成交,部分成交的委托保留在撮合队列中继续交易。试利用单链表作为存放委托的数据结构(撮合队列),编写一模拟股票交易的程序,该程序有以下几个功能:

1. 委托申请:

输入:每个委托包括四个数据项,股票编码( 4 位数字)、价格(浮点数)、数量(整数)、买 / 卖( B/S )

输出: a. 程序为每个委托产生一个唯一的序号( %04d ),该序号从 1 开始; b. 每笔成交包括:成交价格( %6.1f )、成交量( %4d )、新的委托序号( %04d )、匹配的委托序号( %04d )。

2. 查询未成交的委托:

输入:股票编码

输出:按撮合队列中委托的顺序,分别输出该股票未成交的委托,每个输出的委托包括:委托序号( %04d )、 股票编码 ( %04d ) 、 价格( %6.1f )、数量( %4d )、 B/S (买 / 卖 )

3. 委托撤消:

输入:要撤消的委托号。

输出:若成功,显示该委托信息,其中委托包括数据项:委托序号、股票编码、价格、数量、 B/S (买 / 卖 ) ;否则显示“ not found ”失败信息。

委托输入格式 : 1 股票编码 价格 数量 买卖

查询输入格式 : 2 股票编码

委托撤销 : .3 委托号

退出: 0

例: (下面的黑斜体为输入,    输入输出格式参见测试用例)

1 0038 20 1000 b

orderid: 0001

1 0278 18 2000 s

orderid: 0002

1 0003 8 5000 b

orderid: 0003

1 0003 12 1000 b

orderid: 0004

1 0003 10 500 b

orderid: 0005

1 0003 11 9000 b

orderid: 0006

1 0003 18 1000 s

orderid: 0007

2 0003

buy orders:

orderid: 0004, stockid:0003, price: 12.0, quantity: 1000, b/s: b

orderid: 0006, stockid:0003, price: 11.0, quantity: 9000, b/s: b

orderid: 0005, stockid:0003, price: 10.0, quantity: 500, b/s: b

orderid: 0003, stockid:0003, price: 8.0, quantity: 5000, b/s: b

sell orders:

orderid: 0007, stockid:0003, price: 18.0, quantity: 1000, b/s: s

3 0006

deleted order:orderid: 0006, stockid:0003, price: 11.0, quantity: 9000, b/s: b

3 0197

not found

2 0003

buy orders:

orderid: 0004, stockid:0003, price: 12.0, quantity: 1000, b/s: b

orderid: 0005, stockid:0003, price: 10.0, quantity: 500, b/s: b

orderid: 0003, stockid:0003, price: 8.0, quantity: 5000, b/s: b

sell orders:

orderid: 0007, stockid:0003, price: 18.0, quantity: 1000, b/s: s

1 0003 9 1200 s

orderid: 0008

deal--price: 10.5 quantity:1000 sellorder:0008 buyorder:0004

deal--price: 9.5 quantity: 200 sellorder:0008 buyorder:0005

2 0003

buy orders:

orderid: 0005, stockid:0003, price: 10.0, quantity: 300, b/s: b

orderid: 0003, stockid:0003, price: 8.0, quantity: 5000, b/s: b

sell orders:

orderid: 0007, stockid:0003, price: 18.0, quantity: 1000, b/s: s

注意:

1、当查询未成交委托时,如果没有委托,仍要输出“buy orders:”或“sell orders: ”。

2、输入的委托price>=0。

3、输入的委托quantity>=0,当接受一个新的委托时,首先根据委托的股票编码和价格与现有队列中的委托进行撮合,若撮合后有剩余的数量没有得到满足(即quantity>0),则将新委托插入到相应队列中。

4、当输入委托quantity==0且现有队列中有价格合适可以成交的委托,认为交易成功,输出交易信息。

测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 1 9990 8 1000 s↵
  2. 1 0001 9 500 s↵
  3. 1 0001 8 200 s↵
  4. 1 0001 12 1000 s↵
  5. 1 0001 10 1000 b↵
  6. 2 0001↵
  7. 0↵
以文本方式显示
  1. orderid: 0001↵
  2. orderid: 0002↵
  3. orderid: 0003↵
  4. orderid: 0004↵
  5. orderid: 0005↵
  6. deal--price:   9.0  quantity: 200  buyorder:0005  sellorder:0003↵
  7. deal--price:   9.5  quantity: 500  buyorder:0005  sellorder:0002↵
  8. buy orders:↵
  9. orderid: 0005, stockid:0001, price:   10.0, quantity:  300, b/s: b↵
  10. sell orders:↵
  11. orderid: 0004, stockid:0001, price:   12.0, quantity: 1000, b/s: s↵
1秒64M0
测试用例 2以文本方式显示
  1. 1 2222 10 1000 b↵
  2. 1 2222 9 2000 b↵
  3. 1 2222 10 2000 b↵
  4. 2 2222↵
  5. 3 0003↵
  6. 1 2222 9 5000 s↵
  7. 0↵
以文本方式显示
  1. orderid: 0001↵
  2. orderid: 0002↵
  3. orderid: 0003↵
  4. buy orders:↵
  5. orderid: 0001, stockid:2222, price:   10.0, quantity: 1000, b/s: b↵
  6. orderid: 0003, stockid:2222, price:   10.0, quantity: 2000, b/s: b↵
  7. orderid: 0002, stockid:2222, price:    9.0, quantity: 2000, b/s: b↵
  8. sell orders:↵
  9. deleted order:orderid: 0003, stockid:2222, price:   10.0, quantity: 2000, b/s: b↵
  10. orderid: 0004↵
  11. deal--price:   9.5  quantity:1000  sellorder:0004  buyorder:0001↵
  12. deal--price:   9.0  quantity:2000  sellorder:0004  buyorder:0002↵
1秒

代码如下: 

(copy了别人的代码,本来想改一下,但是不知道怎么没改成,优化了几次都报错了,结构这块我还是学的不太好)

#include <stdio.h>
#include <stdlib.h>
int flag;
typedef struct Node
{
    int orderid;
    int stockid;
    float price;
    int quantity;
    char type;
    struct Node *next;
} NODE;

int Min(int a, int b)
{
    return a <= b ? a : b;
}
NODE *head1, *head2, *p; // buy&sell
void InitB()
{
    head1 = (NODE *)malloc(sizeof(NODE));
    head1->orderid = -1;
    head1->stockid = -1;
    head1->price = -1.0;
    head1->quantity = -1;
    head1->type = 'x';
    head1->next = NULL;
}
void InitS()
{
    head2 = (NODE *)malloc(sizeof(NODE));
    head2->orderid = -1;
    head2->stockid = -1;
    head2->price = -1.0;
    head2->quantity = -1;
    head2->type = 'x';
    head2->next = NULL;
}
// void Init(NODE *t)
// {
//     t=(NODE *)malloc(sizeof(NODE));
//     t->orderid = -1;
//     t->stockid = -1;
//     t->price = -1.0;
//     t->quantity = -1;
//     t->type = 'x';
//     t->next = NULL;
// }好奇怪,为什么不能这样合并,基础太差了
void SaveB(NODE *p)
{
    NODE *q = head1, *q_pre;
    int flag1 = 0;
    while (q->next != NULL)
    {
        q_pre = q;
        q = q->next;
        if (p->stockid == q->stockid)
        {
            flag1 = 1;
            while (q != NULL && (q->price > p->price || q->price == p->price) && q->stockid == p->stockid)
            {
                q_pre = q;
                q = q->next;
            }
            q_pre->next = p;
            p->next = q;
            break;
        }
    }
    if (flag1 == 0)
    {
        p->next = head1->next;
        head1->next = p;
    }
}
void SaveS(NODE *p)
{
    NODE *q = head2, *q_pre;
    int flag1 = 0;
    while (q->next != NULL)
    {
        q_pre = q;
        q = q->next;
        if (p->stockid == q->stockid)
        {
            flag1 = 1;
            while (q != NULL && (q->price < p->price || q->price == p->price) && q->stockid == p->stockid)
            {
                q_pre = q;
                q = q->next;
            }
            q_pre->next = p;
            p->next = q;
            break;
        }
    }
    if (flag1 == 0)
    {
        p->next = head2->next;
        head2->next = p;
    }
}
void DeleteB(NODE *p)
{
    NODE *x = head1;
    while (x->next->orderid != p->orderid)
        x = x->next;
    x->next = p->next;
}
void DeleteS(NODE *p)
{
    NODE *x = head2;
    while (x->next->orderid != p->orderid)
        x = x->next;
    x->next = p->next;
}
void Delete()
{
    NODE *x;
    x = head1;
    while (x->next != NULL)
    {
        x = x->next;
        if (x->quantity == 0)
            DeleteB(x);
    }
    x = head2;
    while (x->next != NULL)
    {
        x = x->next;
        if (x->quantity == 0)
            DeleteS(x);
    }
}

int main()
{
    int choice, stockid, quantity, orderid = 1;
    float price;
    char bs;
    InitB();
    InitS();
    // Init(head1);
    // Init(head2);
    while ((scanf("%d ", &choice)) && choice != 0)
    {
        if (choice == 0)
        {
            exit(0);
            break;
        }
        else if (choice == 1)
        {
            scanf("%d %f %d %c", &stockid, &price, &quantity, &bs);
            getchar();
            p = (NODE *)malloc(sizeof(NODE));
            p->orderid = orderid++;
            p->price = price;
            p->stockid = stockid;
            p->quantity = quantity;
            p->type = bs;
            printf("orderid: %04d\n", p->orderid);
            if (bs == 'b')
            {
                NODE *q = head2;
                while (q->next != NULL)
                {
                    q = q->next;
                    if (q->stockid != p->stockid)
                        continue;
                    else
                    {
                        if (q->price < p->price || q->price == p->price)
                        {
                            int d_quantity = Min(p->quantity, q->quantity);
                            printf("deal--price:%6.1f  quantity:%4d  buyorder:%04d  sellorder:%04d\n", (p->price + q->price) / 2.0, d_quantity, p->orderid, q->orderid);
                            p->quantity -= d_quantity;
                            q->quantity -= d_quantity;
                            if (q->quantity == 0)
                                DeleteS(q);
                            if (p->quantity == 0)
                                break;
                        }
                        else
                            continue;
                    }
                }
                if (p->quantity == 0)
                    free(p);
                else
                    SaveB(p);
            }
            else
            {
                NODE *q = head1;
                while (q->next != NULL && p->quantity != 0)
                {
                    q = q->next;
                    if (q->stockid != p->stockid)
                        continue;
                    else
                    {
                        if (q->price > p->price || q->price == p->price)
                        {
                            int d_quantity = Min(p->quantity, q->quantity);
                            printf("deal--price:%6.1f  quantity:%4d  sellorder:%04d  buyorder:%04d\n", (p->price + q->price) / 2.0, d_quantity, p->orderid, q->orderid);
                            p->quantity -= d_quantity;
                            q->quantity -= d_quantity;
                            if (q->quantity == 0)
                                DeleteB(q);
                        }
                        else
                            continue;
                    }
                }
                if (p->quantity == 0)
                    free(p);
                else
                    SaveS(p);
            }
            Delete();
        }
        else if (choice == 2)
        {
            int stockid1;
            scanf("%d", &stockid1);
            getchar();
            printf("buy orders:\n");
            p = head1;
            while (p->next != NULL)
            {
                p = p->next;
                if (p->stockid == stockid1 && p->quantity != 0)
                    printf("orderid: %04d, stockid:%04d, price: %6.1f, quantity: %4d, b/s: %c\n", p->orderid, p->stockid, p->price, p->quantity, p->type);
            }
            printf("sell orders:\n");
            p = head2;
            while (p->next != NULL)
            {
                p = p->next;
                if (p->stockid == stockid1 && p->quantity != 0)
                    printf("orderid: %04d, stockid:%04d, price: %6.1f, quantity: %4d, b/s: %c\n", p->orderid, p->stockid, p->price, p->quantity, p->type);
            }
        }
        else if (choice == 3)
        {
            int orderid1;
            scanf("%d", &orderid1);
            getchar();
            flag = 0;
            p = head1;
            while (p->next != NULL)
            {
                p = p->next;
                if (p->orderid == orderid1)
                {
                    flag = 1;
                    printf("deleted order:orderid: %04d, stockid:%04d, price: %6.1f, quantity: %4d, b/s: %c\n", p->orderid, p->stockid, p->price, p->quantity, p->type);
                    DeleteB(p);
                    break;
                }
            }
            p = head2;
            while (p->next != NULL && !flag)
            {
                p = p->next;
                if (p->orderid == orderid1)
                {
                    flag = 1;
                    printf("deleted order:orderid: %04d, stockid:%04d, price: %6.1f, quantity: %4d, b/s: %c\n", p->orderid, p->stockid, p->price, p->quantity, p->type);
                    DeleteS(p);
                    break;
                }
            }
            if (flag == 0)
                printf("not found\n");
            flag = 0;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值