[英]Algorithm to compare two date time stamps
我需要在 C 中实现时间戳比较(不使用任何库)。
我正在尝试找出最佳算法,因为该例程将被大量使用。
我的输入数据是两个时间戳,a 和 b,每个时间戳包含以下内容:
year
month
day
hour
minute
在 C 伪代码中:
struct Timestamp {
int year;
int month;
int day;
int hour;
int minute;
};
struct Timestamp a;
struct Timestamp b;
我正在尝试几种方法,包括嵌套 if 和组合每个值的开关:
int timestamp_comparison(int a, int b) {
if(a>b) return 2;
if(a=b) return 1;
if(a<b) return 0;
}
...
c_year = timestamp_comparison(a.year, b.year);
c_month = timestamp_comparison(a.month, b.month);
c_day = timestamp_comparison(a.day, b.day);
c_hour = timestamp_comparison(a.hour, b.hour);
c_minute = timestamp_comparison(a.minute, b.minute);
comparison = c_year * 10000 + c_month * 1000 + c_day * 100 + c_hour * 10 + c_minute;
...
但我想知道是否有一个我可以利用的算法。 我不喜欢使用外部库。
我建议不要使用返回值0
、 1
和2
,而是使用<0
、 0
和>0
。 这个比较常见,匹配strcmp
等、 qsort
或bsearch
的语义,可以使用简单的减法和与 0 的比较来实现。
/*
* @retval <0 if a < b
* @retval 0 if a == b
* @retval >0 if a > b
*/
int compare_timestamps(struct Timestamp a, struct Timestamp b)
{
int result;
result = a.year - b.year;
if(result != 0) return result;
result = a.month - b.month;
if(result != 0) return result;
result = a.day - b.day;
if(result != 0) return result;
result = a.hour - b.hour;
if(result != 0) return result;
result = a.minute - b.minute;
return result;
}
正如 Jim Mischel 的评论中提到的,该算法假设减法不会导致整数翻转。 这对month
、 day
、 hour
和minute
字段的正常值有效。 这是对“通常”年份值的合理假设。 如果abs(a.year) + abs(b.year) > INT_MAX
year
字段abs(a.year) + abs(b.year) > INT_MAX
。 要处理整个INT_MIN
.. INT_MAX
范围内的year
值,必须更改算法。
比较时间戳时,有两个问题会起作用
年份范围
如果.year
的使用范围是[INT_MIN...INT_MAX]
,请避免a.year - b.year
因为它可能会溢出。
主要价值
成员总是在他们的主要范围内吗? 示例: minute
是否在 0-59 范围内?
是这样,一个简单的比较和返回 -1,0,1 使用常见的 C 习语(a>b) - (a<b)
,这是许多编译器识别并发出有效代码的东西。
int timestamp_compare(const struct Timestamp *ts2, const struct Timestamp *ts1) {
if (ts1->year != ts2->year) return (ts2->year > ts1->year) - (ts2->year < ts1->year);
if (ts1->month != ts2->month) return (ts2->month > ts1->month) - (ts2->month < ts1->month);
if (ts1->day != ts2->day) return (ts2->day > ts1->day) - (ts2->day < ts1->day);
if (ts1->hour != ts2->hour) return (ts2->hour > ts1->hour) - (ts2->hour < ts1->hour);
return (ts2->day > ts1->day) - (ts2->day < ts1->day);
}
如果不是,请形成分钟的线性计数,然后进行比较。
long long minutes(const struct Timestamp *ts) {
return ((tbd_day_number(ts->year, ts->month, ts->day)*24LL + ts->hour)*60 + ts->minute;
}
int timestamp_compare(const struct Timestamp *ts2, const struct Timestamp *ts1) {
long long m1 = minutes(ts1);
long long m2 = minutes(ts2);
return (m2 > m1) - (m2 < m1);
}
如果您的结构以排序方式包含其成员,例如在您的情况下(年份比月份更重要,依此类推...)并且由于在结构中,成员“最有可能”以连续方式存储:
请参阅: 使用 C 结构成员的连续内存
您可以尝试使用逐字节比较,如下所示:
#include <stdlib.h>
// members of struct are stored contigously
struct Timestamp
{
int year;
int month;
int day;
int hour;
int minute;
};
int timestamp_comparison(const struct Timestamp a, const struct Timestamp b)
{
unsigned i;
unsigned struct_size = sizeof(struct Timestamp) / sizeof(int);
const int* t1 = (const int*)&a;
const int* t2 = (const int*)&b;
// compare byte by byte
for (i = 0; i < struct_size; i++)
{
if (*t1 != *t2)
return *t1 - *t2;
++t1;
++t2;
}
return 0;
}
int main()
{
// example
struct Timestamp a = {1, 1, 2, 1, 1};
struct Timestamp b = {1, 1, 1, 7, 1};
int comp = timestamp_comparison(a, b);
return 0;
}
我并不是说这比已经发布的答案更好,只是不同。 对于像您这样的任何其他结构,它的工作方式相同。
这里有一个小改进:
您的 PC 以二进制方式运行,因此以 2 为基数是他最擅长的
你可以替换:
comparison = c_year * 10000 + c_month * 1000 + c_day * 100 + c_hour * 10 + c_minute;
by(您的值都低于 4),因此您可以:
comparison = c_year * 256 + c_month * 64 + c_day * 16 + c_hour *4 + c_minute;
或者这个(可读性较差但“没有”算术):
comparison = c_year << 8 | c_month <<6 | c_day <<4 | c_hour <<2 | c_minute;
但是,如果您真的通过这种方式提高了速度,则只能通过分析进行验证。
根据您的数据,仅比较您需要的数据可能会更快:
int val;
if(1!=(val=timestamp_comparison(a.year, b.year)))
return val;
if(1!=(val=timestamp_comparison(a.month, b.month)))
return val;
if(1!=(val=timestamp_comparison(a.c_day, b.c_day)))
return val;
if(1!=(val=timestamp_comparison(a.c_hour, b.c_hour)))
return val;
return timestamp_comparison(a.c_minute, b.c_minute);
但正如我上面提到的,在优化方面,分析是你的朋友。
ps
if(a>b) return 2;
if(a=b) return 1;
if(a<b) return 0;
是一个有点不寻常的定义。 更常见的是:
if(a>b) return value >=1
if(a=b) return 0;
if(a<b) return value <=-1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.