我的任务是用户输入包含月份,日期和年份的n行,格式为“1月12日99”。
我必须按年代顺序排序日期列表,首先按年使用qsort,然后按天计算,然后按月计算。
我的问题是我不确定如何对多个索引进行qsort。我已经完成了今年的工作,但是在那之后我不知道如何在当天进行排序,因为它肯定会在白天进行排序,但是这些年份会再次混乱?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int (*compfn)(const void*, const void*);
struct date
{
char month[9]; //Maximum of 9 characters in a month
int day; //The day of the month (e.g. 18)
int year; //The year of the date
};
int sortDates(struct date *elem1, struct date *elem2)
{
if (elem1 -> year < elem2 -> year)
{
return -1;
}
else
if (elem1->year > elem2->year)
{
return 1;
}
else
return 0;
}
main()
{
int n;
int i;
scanf("%d", &n);
struct date *list;
list = (struct date *)malloc((n * sizeof(struct date)));
for(i = 0; i < n; i++)
{
scanf("%s %d %d", list[i].month, &list[i].day, &list[i].year);
}
qsort(list, sizeof(list), sizeof(struct date), (compfn)sortDates);
for(i = 0; i < n; i++)
{
printf("%s %d %d\n", list[i].month, list[i].day, list[i].year);
}
}
编辑:所以我有排序工作,我正在努力将整数转换回打印排序列表时的月份字符串表示。这是代码,我得到“数组下标不是整数”错误。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int (*compfn)(const void*, const void*);
struct date
{
int month;
int day; //The day of the month (e.g. 18)
int year; //The year of the date
};
char* months[]= {
"January", "February",
"March", "April",
"May", "June",
"July", "August",
"September", "October",
"November", "December"};
int getMonth(char tempMonth[])
{
int i = 0;
for(i = 0; i<12; i++)
{
if(tempMonth == months[i]) return i;
}
return 0;
}
char getStringMonth(struct date month)
{
return months[month];
}
int sortDates(struct date *elem1, struct date *elem2)
{
if (elem1 -> year < elem2 -> year)
{
return -1;
}
else
if (elem1->year > elem2->year)
{
return 1;
}
if ( elem1->month < elem2->month )
{
return -1;
}
else
if ( elem1->month > elem2->month )
{
return 1;
}
if ( elem1->day < elem2->day )
{list
return -1;
}
else
if ( elem1->day > elem2->day )
{
return 1;
}
else
return 0;
}
main()
{
int n;
int i;
char tempMonth[255]; //Used to store the month until checked
scanf("%d", &n);list
struct date *list;
list = (struct date *)malloc((n * sizeof(struct date)));
for(i = 0; i < n; i++)
{
scanf("%s %d %d", tempMonth, &list[i].day, &list[i].year);
list[i].month = getMonth(tempMonth);
}
qsort(list, sizeof(list), sizeof(struct date), (compfn)sortDates);
for(i = 0; i < n; i++)
{
printf("%s %d %d", getStringMonth(list[i].month), list[i].day, list[i].year);
}
}
答案 0 :(得分:5)
请记住free
记住malloc
的记忆。
在下面的代码中,我假设月份存储为数字,但我在你的结构中看到情况并非如此。我会将输入的月份从字符串转换为数字,以简化排序过程。
int sortDates(struct date* elem1, struct date* elem2)
{
if ( elem1->year < elem2->year)
return -1;
else if ( elem1->year > elem2->year )
return 1;
/* here you are sure the years are equal, so go on comparing the months */
if ( elem1->month < elem2->month )
return -1;
else if ( elem1->month > elem2->month )
return 1;
/* here you are sure the months are equal, so go on comparing the days */
if ( elem1->day < elem2->day )
return -1;
else if ( elem1->day > elem2->day )
return 1;
else
return 0; /* definitely! */
}
还要注意这个声明:char month[9];
,9月是9个字符,但你需要在C中使用终结符char '\0'
来关闭字符串。为了避免这种问题,我会声明一个包含所有月份的数组,以允许检查并将月份从字符串转换为数字:
char* allMonths[]=
"January", "February",
"March", "April",
"May", "June",
"July", "August",
"September", "October",
"November", "December";
char tmpMonth[255];
scanf("%s %d %d", tmpMonth, &list[i].day, &list[i].year);
/* convert tmpMonth to a number by finding it in the allMonths and throw error if not found */
答案 1 :(得分:2)
当两年相等时,不要返回0,只需复制粘贴逻辑并将其应用到几个月。再过几天。就是这样。
顺便说一句,如果你想按时间顺序排序,你必须首先排序年份,然后是月份,然后是日期。不是几天而是几个月。
你应该将月份存储为数字,而不是字符串:按时间顺序排列会更容易。
最后,我将函数命名为compareDates
,而不是sortDates
。
答案 2 :(得分:1)
不是在最后else
上返回0,而是比较另一个字段:
else {
if (elem1->day < elem2->day) {
return -1;
}
else if (elem1->day > elem2->day) {
return 1;
}
else {
//compare months
}
}
基本理念是:
答案 3 :(得分:1)
你所拥有的一年(主要关键)是好的。当年份相等时,您只需稍微调整即可使用月份(次要键),您可以根据需要将其扩展到多个级别的键。
伪代码仅用于作业,我担心:
def compare (date1, date2):
if date1.year > date2.year:
return 1
if date1.year < date2.year:
return -1
# Years are equal here.
if date1.month > date2.month
return 1
if date1.month < date2.month
return -1
# Years and months are equal here.
if date1.day > date2.day
return 1
if date1.day < date2.day
return -1
# Years, months and days are all equal here.
return 0
通过执行这样的单个“分层”比较功能,您不必担心月份排序搞砸了多年的顺序,因为它在 月内按排序在年内。
而且,正如你所看到的,我不是以下的忠实粉丝:
if condition:
return something
else:
carry on
成语。 else
完全没必要,并且可以在不需要的情况下导致大量缩进。我更喜欢:
if condition:
return something
carry on
实际的排序方法最好将这些月份名称转换为数值,以便比较效果更好。这可能最好留给另一个问题,但你可能会把一些字符串数组合在一起:
char *months[] = {"January", "February", ... "December"};
和for
循环将名称转换为0
到11
范围内的值。
答案 4 :(得分:0)
您应该更改比较函数sortDates
,并根据年份相等的日期以及日期和月份相等的月份来做出决定。