You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按日期字符串排序数据结构并简化现有C语言排序代码?

如何按包含日期的字符串对数据结构进行排序?

问题背景

需要处理一系列欧洲国家首都的记录(包含首都名称、人口、主要公共假日名称、假日日期),其中假日日期是月份 日期格式的字符串(例如August 24),要求按假日日期的日历顺序对这些记录重新排序。现有C语言实现代码冗长且存在逻辑错误,需要优化。

现有代码的问题

原代码存在以下明显问题:

  • Sort_by_Date是void类型函数,却在内部使用return返回布尔值,属于语法错误
  • 存在笔误:if (day1 > day1),应该是day1 > day2
  • 冒泡排序的嵌套循环中重复解析日期,效率低下
  • 代码逻辑耦合严重,日期解析和排序逻辑混在一起,可读性差

优化方案

我们可以通过以下方式简化实现:

  1. 拆分日期解析逻辑:将日期字符串转换为可直接比较的整数键(例如用MMDD格式的数值,1月5日对应0105,12月31日对应1231),这样排序时只需比较数值大小
  2. 使用标准库排序函数:利用C标准库的qsort函数替代手写冒泡排序,代码更简洁且性能更优

具体实现代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MONTHS_NUM 12
const char *months[MONTHS_NUM] = {
    "jan", "feb", "mar", "apr", "may", "jun", 
    "jul", "aug", "sep", "oct", "nov", "dec"
};

typedef struct capital {
    char name[20];
    long int population;
    char holiday[60];
    char date[15];
} CAPITAL;

// 将日期字符串转换为MMDD格式的整数键,用于排序比较
int date_to_key(const char *date_str) {
    int day;
    char month_abbr[4];
    // 解析日期字符串(格式为"月份 日期",对应%3s %d)
    sscanf(date_str, "%3s %d", month_abbr, &day);
    
    // 匹配月份对应的索引
    int month_idx = -1;
    for (int i = 0; i < MONTHS_NUM; i++) {
        if (strcmp(months[i], month_abbr) == 0) {
            month_idx = i + 1; // 月份从1开始(1-12)
            break;
        }
    }
    
    // 返回MMDD格式的数值,例如1月5日返回105,12月31日返回1231
    return month_idx * 100 + day;
}

// qsort的比较函数:按日期键升序排序
int compare_capital_by_date(const void *a, const void *b) {
    const CAPITAL *cap_a = (const CAPITAL *)a;
    const CAPITAL *cap_b = (const CAPITAL *)b;
    
    int key_a = date_to_key(cap_a->date);
    int key_b = date_to_key(cap_b->date);
    
    return key_a - key_b; // 升序排序,若要降序则返回key_b - key_a
}

// 排序入口函数
void Sort_by_Date(CAPITAL arr[], int nc) {
    qsort(arr, nc, sizeof(CAPITAL), compare_capital_by_date);
}

// 测试示例
int main() {
    CAPITAL capitals[] = {
        {"London", 9002488, "Christmas Day", "dec 25"},
        {"Paris", 2161000, "Bastille Day", "jul 14"},
        {"Berlin", 3645000, "German Unity Day", "oct 3"}
    };
    int count = sizeof(capitals) / sizeof(CAPITAL);
    
    Sort_by_Date(capitals, count);
    
    // 输出排序结果
    for (int i = 0; i < count; i++) {
        printf("首都:%s,假日:%s(%s)\n", 
               capitals[i].name, capitals[i].holiday, capitals[i].date);
    }
    
    return 0;
}

代码说明

  • date_to_key函数:负责将月份 日期格式的字符串转换为整数键,解决日期字符串无法直接比较的问题
  • compare_capital_by_date函数:作为qsort的回调函数,实现两个CAPITAL结构体的日期比较逻辑
  • Sort_by_Date函数:现在只需调用qsort,代码极其简洁,无需手写排序循环
  • 修正了原代码中日期解析的格式错误(原代码用%d %3s,但输入格式是月份 日期,应该是%3s %d)

内容的提问来源于stack exchange,提问作者mary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:45:33