京東筆試-交易清單

題目要求:
1、使用c語言實現,不能使用c++的stl容器,map、vector等等
2、自己定義數據結構
3、如果需要排序,自己寫排序算法

股票交易中,高峯期委託買賣數量是十分大的,尤其在9:30分左右,而證券公司關心的搶手的信息條數會遠小於委託買賣數量。實際情況是題目中的n會非常大,而s很小,因此需要考慮算法的時間複雜度。

題目如下:
京東筆試-交易清單(京東2016實習生真題)
題目描述
金融證券行業超好的薪酬待遇,吸引了大批的求職者前往應聘,小東也不例外,準備應聘一家證券公司。面試官爲考察她的數據分析、處理和編碼能力,爲她準備了以下問題。
股票交易中,委託是指股票交易者在證券公司買賣股票。每手委託包括一個委託單號i、價格pi、買入或賣出標記di及交易數量qi。
交易處理中,需要把同類業務(買入或賣出)中相同價格的所有委託合併起來,形成一個清單。清單的第一部分爲按價格降序排列的合併後的賣出委託,緊隨其後的是按相同順序排列的買入合併委託。證券公司比較關心的是比較搶手的s條合併委託信息,需要得到買入及賣出最搶手的s條合併委託。對於買入委託,搶手的是指報價高的委託,而賣出委託中報價低的較爲搶手。若買或賣的合併委託數小於s條,則全部列入清單中。
現在小東拿到的是n個委託,請你幫忙找出最搶手的s個合併委託。

輸入
輸入有若干組,每組的第一行爲兩個正整數n和s(1<=n<=1000,1<=s<=50),分別表示委託數和最搶手的清單數,接下來的n行爲具體的委託信息,每行包含3部分,第一部分爲一個字母‘B’或‘S’,表示買入或賣出,後兩部分爲兩個整數p和q,表示報價和數量。任何賣出委託的報價都比買入委託的報價高。

輸出
輸出不超過2s行合併委託清單,格式與輸入相同。

樣例輸入
6 2
B 10 3
S 50 2
S 40 1
S 50 6
B 20 4
B 25 10

樣例輸出
S 40 1
S 50 8
B 25 10
B 20 4

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef struct {
  unsigned int in;
  unsigned int out;
}InOut;
typedef struct {
  char type; // transaction type, 'B' means buy, 'S' means sell.
  unsigned int price;
  unsigned int quantity;
} TransData;
// DDL - Doubly Linked List.
typedef struct _node {
  TransData data;
  struct _node *next, *prev;
}DDLNode;
typedef struct _list {
  DDLNode *head, *tail;
}DDL;
DDLNode* CreateDDLNode(TransData *pData);
void ShowDDLNode(DDLNode *pNode);
void InitDDL(DDL *pddl);
bool IsEmptyDDL(DDL *pList);
bool IsHeadNode(DDL *pList, DDLNode *pNode);
bool IsTailNode(DDL *pList, DDLNode *pNode);
// DDDL - Descending DDL.
int InsertToDDDL(DDL *pList, TransData *pData);
void ShowDDLFromHead(DDL *pList, unsigned int cnt);
void ShowDDLFromTail(DDL *pList, unsigned int cnt);
#define CHECK_NULL_POINTER(ptr) \
  if(!ptr){ \
    fprintf(stderr, "null pointer at %s, line %d\n", __FUNCTION__, __LINE__); \
    exit(-1); \
  }
int main(){
  InOut io = {0,0};
  DDL sddl, bddl;
  int i;
  
  printf("Please input transactions count (in out):");
  scanf(" %u %u", &io.in, &io.out);
  //printf("io(%u, %u)\n", io.in, io.out);
  printf("Please input the raw transaction data.\"('B' price quantity)\" for buying stocks, \"('S' price quantity)\" for selling stocks.\n");
  TransData record[io.in];
  for(i = 0; i < io.in; ){
    scanf(" %c %u %u", &(record[i].type), &(record[i].price), &(record[i].quantity));  
    //printf("record[%d]:%c, %u, %u\n", i, record[i].type, record[i].price, record[i].quantity);  
    if(record[i].type != 'B' && record[i].type != 'S'){
      printf("Wrong transaction type. It must be 'B' or 'S'!\n");
      continue;
    }
    else{
      ++i;
    }
  }
  InitDDL(&sddl);
  InitDDL(&bddl);
  for(i = 0; i < io.in; ++i){
    //printf("\ninsert record[%d]: %c %u %u\n", i, record[i].type, record[i].price, record[i].quantity);  
    if(record[i].type == 'B'){
      InsertToDDDL(&bddl, &(record[i]) );
    }
    else if(record[i].type == 'S'){
      InsertToDDDL(&sddl, &(record[i]) );
    }
  } 
  printf("\noutput:\n");
  ShowDDLFromTail(&sddl, io.out);
  ShowDDLFromHead(&bddl, io.out);
  return 0;
}
DDLNode* CreateDDLNode(TransData *pData){
  DDLNode *pNewNode = (DDLNode *)malloc(sizeof(DDLNode));
  CHECK_NULL_POINTER(pNewNode);
  if(pData){
    pNewNode->data.type = pData->type;
    pNewNode->data.price = pData->price;
    pNewNode->data.quantity = pData->quantity;
  }
  else{
    pNewNode->data.type = 0;
    pNewNode->data.price = 0;
    pNewNode->data.quantity = 0;
  }
  pNewNode->next = NULL;
  pNewNode->prev = NULL;
}
void ShowDDLNode(DDLNode *pNode){
  if(pNode)
    printf("%c %u %u %p %p %p\n", pNode->data.type, pNode->data.price, pNode->data.quantity, pNode, pNode->prev, pNode->next);
  else
    printf("null node\n");
}
void InitDDL(DDL *pList){
  CHECK_NULL_POINTER(pList);
  pList->head = NULL;
  pList->tail = NULL;
}
bool IsEmptyDDL(DDL *pList){
  CHECK_NULL_POINTER(pList);
  return pList->head == NULL && pList->tail == NULL;
}
bool IsHeadNode(DDL *pList, DDLNode *pNode){
  CHECK_NULL_POINTER(pList);
  return pList->head == pNode;
}
bool IsTailNode(DDL *pList, DDLNode *pNode){
  CHECK_NULL_POINTER(pList);
  return pList->tail == pNode;
}
/*Function: create a new node to save data, and insert or merge it to descending DDL. 
 *@return value: 0 : success, -1 : fail. 
 */
int InsertToDDDL(DDL *pList, TransData *pData){
  CHECK_NULL_POINTER(pList);
  if(IsEmptyDDL(pList) ){
    DDLNode *pNewNode = CreateDDLNode(pData);
    pList->head = pNewNode;
    pList->tail = pNewNode;
    return 0;
  }
  DDLNode *pNode = pList->head;
  while(pNode){
    if(pNode->data.price == pData->price){
      pNode->data.quantity += pData->quantity;
      return 0; 
    }
    if(pNode->data.price < pData->price){
      //Insert a new node before pNode.
      DDLNode *pNewNode = CreateDDLNode(pData);
      if(IsHeadNode(pList, pNode) ){
        pNewNode->next = pNode;
        pNode->prev = pNewNode;
        pList->head = pNewNode;
        return 0;
      }
      pNewNode->prev = pNode->prev;
      pNode->prev->next = pNewNode;
      pNewNode->next = pNode;
      pNode->prev = pNewNode;
      return 0;
    }
    if(pNode->data.price > pData->price){
      if(IsTailNode(pList, pNode) ){
        //Insert a new node after pNode.
        DDLNode *pNewNode = CreateDDLNode(pData);
        pNode->next = pNewNode;
        pNewNode->prev = pNode;
        pList->tail = pNewNode;
        return 0;
      }
      pNode = pNode->next;
    }
  }
  fprintf(stderr, "Fail to insert node to descending DDL.");
  return -1;
}
void ShowDDLFromHead(DDL *pList, unsigned int cnt){
  CHECK_NULL_POINTER(pList);
  unsigned int i=0;
  DDLNode *pNode = pList->head;
  for(; i < cnt && pNode; ++i, pNode = pNode->next){
    printf("%c %u %u\n", pNode->data.type, pNode->data.price, pNode->data.quantity);
  }
}
void ShowDDLFromTail(DDL *pList, unsigned int cnt){
  CHECK_NULL_POINTER(pList);
  unsigned int i=0;
  DDLNode *pNode = pList->tail;
  for(; i < cnt && pNode; ++i, pNode = pNode->prev){
    printf("%c %u %u\n", pNode->data.type, pNode->data.price, pNode->data.quantity);
  }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章