Beijing East Written Test - Transaction List

Posted by andynick on Tue, 28 May 2019 01:38:40 +0200

Topic Requirements:
1. Implemented in c language, can't use stl container, map, vector, etc. of c++.
2. Define your own data structure
3. Write your own sorting algorithm if you need to sort

In stock trading, the number of entrusted transactions in peak period is very large, especially around 9:30, and the number of information items that securities companies are concerned about will be far less than the number of entrusted transactions. The actual situation is that n in the title will be very large, while s is very small, so the time complexity of the algorithm needs to be considered.

The title is as follows:
Beijing East Written Examination - Transaction List (Beijing East 2016 Interns True Question)
Title Description
Excellent remuneration in the financial and securities industry has attracted a large number of job seekers to apply for jobs, Xiaodong is no exception, ready to apply for a securities company. To examine her data analysis, processing and coding skills, the interviewer prepared the following questions for her.
In stock trading, entrustment means that stock traders buy and sell stocks in securities companies. Each consignment includes a consignment number i, price pi, buy or sell mark di and transaction quantity qi.
In transaction processing, all commissions of the same price in the same kind of business (buy or sell) need to be merged to form a list. The first part of the list is the sale delegation after the merger in descending order of price, followed by the purchase merger delegation in the same order. Securities companies are more concerned about the more competitive S-merger Commission information, need to buy and sell the most popular S-merger commission. For the purchase commission, the competitor refers to the Commission with high quotation, while the one with low quotation in the sale Commission is the competitor. If the number of merger commissions to buy or sell is less than s, they will all be included in the list.
Now Xiaodong has n commissions, please help find out the most popular s merger commissions.

input
There are several groups of input. The first behavior of each group has two positive integers n and s (1 <=n<=1000, 1 <=s<=50), representing the number of delegates and the most popular list, respectively. The next n behavior contains three parts in each line. The first part is a letter'B'or'S', indicating buy or sell, and the last two parts are two integers p and q, indicating quotation and quantity. Any offer to sell a consignment is higher than that to buy a consignment.

output
Output not more than 2s line merge delegation list, format and input the same.

sample input
6 2
B 10 3
S 50 2
S 40 1
S 50 6
B 20 4
B 25 10

sample output
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);
  }
}


Topics: less C