C语言嵌套循环下订单重复打印问题及替代方案问询
订单合并打印问题及解决方案
问题背景
开发简易交易程序,需对buffer中存储的商品(如GPU、ROUTER)的BUY/SELL订单做合并打印:
- 相同action、item、price的订单,合并总数量并显示累计订单数
- 同商品不同价格的订单,需分别显示
当前嵌套循环处理存在重复打印问题:重复提交同一订单后,会同时输出合并后的订单与新增原订单。曾尝试在exchange_order结构体中添加duplicate标记跟踪已处理订单,但未彻底解决。因订单列表较短,希望采用当前订单与已处理历史订单对比,重复则跳过的方案,寻求具体实现。
初始结构体与代码
struct exchange_order_book { int number_of_orders; int exchange_fees; struct exchange_order all_orders[100]; }; struct exchange_order { int quantity; int price; char action[5]; char item[20]; int traderId; int orderId; }; void print_buy_levels(){ for(int i = 0; i<buffer_size; ++i){ int buys = 0, sells = 0; double buy_prices[100] = {0}; // 假设最多100个唯一价格 double sell_prices[100] = {0}; // 假设最多100个唯一价格 int buy_count = 0, sell_count = 0; // 遍历所有订单 for(int j = 0; j<exchange.number_of_orders; ++j){ if(strcmp(buffer[i],exchange.all_orders[j].item) == 0){ if(strcmp(exchange.all_orders[j].action,"BUY") == 0){ // 检查是否为唯一买入价 int found = 0; for(int k = 0; k < buy_count; ++k){ if(exchange.all_orders[j].price == buy_prices[k]){ found = 1; break; } } if(!found){ buy_prices[buy_count++] = exchange.all_orders[j].price; ++buys; } }else if(strcmp(exchange.all_orders[j].action,"SELL") == 0) { // 检查是否为唯一卖出价 int found = 0; for(int k = 0; k < sell_count; ++k){ if(exchange.all_orders[j].price == sell_prices[k]){ found = 1; break; } } if(!found){ sell_prices[sell_count++] = exchange.all_orders[j].price; ++sells; } } } } printf("%s\tProduct: %s; Buy levels: %d; Sell levels: %d\n",LOG_PREFIX,buffer[i],buys,sells); } }
修改后的代码(未解决问题)
void print_orders() { for (int i = 0; i < buffer_size; ++i) { for (int j = 0; j < exchange.number_of_orders; ++j) { if ( !exchange.all_orders[j].duplicate && strcmp(buffer[i], exchange.all_orders[j].item) == 0) { struct exchange_order current_order = exchange.all_orders[j]; int count = 1; int quantity = current_order.quantity; int is_duplicate = 0; for (int k = j + 1; k < exchange.number_of_orders; ++k) { struct exchange_order next_order = exchange.all_orders[k]; if (current_order.price == next_order.price && strcmp(current_order.item, next_order.item) == 0) { ++count; quantity += next_order.quantity; is_duplicate = 1; next_order.duplicate = true; } } if (!is_duplicate) { printf("%s\t\t%s %d @ $%d (%d order)\n", LOG_PREFIX, current_order.action, quantity, current_order.price, count); } else { printf("%s\t\t%s %d @ $%d (%d orders)\n", LOG_PREFIX, current_order.action, quantity, current_order.price, count); } } } } } struct exchange_order { int quantity; int price; char action[5]; char item[20]; int traderId; int orderId; bool duplicate; };
解决方案:已处理订单对比法
核心思路:遍历订单时,维护一个已处理的唯一订单标记集合,每处理一个订单前,先检查该订单的(action、item、price)组合是否已经被处理过,若已处理则跳过,否则进行合并计算并标记为已处理。
具体实现代码
#include <stdbool.h> #include <string.h> // 辅助结构体:用于标记已处理的唯一订单组合 typedef struct { char action[5]; char item[20]; int price; } ProcessedKey; void print_orders() { ProcessedKey processed[100]; // 存储已处理的唯一订单组合,假设最多100种 int processed_count = 0; // 遍历buffer中的每个商品 for (int i = 0; i < buffer_size; ++i) { const char* target_item = buffer[i]; // 遍历所有订单 for (int j = 0; j < exchange.number_of_orders; ++j) { struct exchange_order* current = &exchange.all_orders[j]; // 只处理当前buffer中的商品订单 if (strcmp(current->item, target_item) != 0) { continue; } // 检查当前订单的组合是否已处理 bool already_processed = false; for (int k = 0; k < processed_count; ++k) { if (strcmp(processed[k].action, current->action) == 0 && strcmp(processed[k].item, current->item) == 0 && processed[k].price == current->price) { already_processed = true; break; } } if (already_processed) { continue; } // 执行合并计算 int total_quantity = current->quantity; int order_count = 1; for (int k = j + 1; k < exchange.number_of_orders; ++k) { struct exchange_order* next = &exchange.all_orders[k]; if (strcmp(next->action, current->action) == 0 && strcmp(next->item, current->item) == 0 && next->price == current->price) { total_quantity += next->quantity; order_count++; } } // 打印合并结果 if (order_count == 1) { printf("%s\t\t%s %d @ $%d (%d order)\n", LOG_PREFIX, current->action, total_quantity, current->price, order_count); } else { printf("%s\t\t%s %d @ $%d (%d orders)\n", LOG_PREFIX, current->action, total_quantity, current->price, order_count); } // 将当前组合标记为已处理 strcpy(processed[processed_count].action, current->action); strcpy(processed[processed_count].item, current->item); processed[processed_count].price = current->price; processed_count++; } } }
方案优势
- 无需修改原
exchange_order结构体,避免侵入式修改 - 逻辑清晰:通过已处理集合过滤重复组合,彻底解决重复打印问题
- 适合短订单列表:时间复杂度为O(n²),在订单量小的场景下性能足够
内容的提问来源于stack exchange,提问作者HyperCoderSuperion
相关产品推荐
相关产品推荐

