搜索
bottom↓
回复: 15

又碰到个算法的问题,想请教各位大大

[复制链接]

出0入0汤圆

发表于 2014-1-9 02:33:30 | 显示全部楼层 |阅读模式
本帖最后由 lswhome 于 2014-1-9 02:35 编辑

就是计算某一时刻是否在某一时间段内:比如从23:25开始到第二天的8:30结束,某一时刻(几点几分)是否在这个时间段内
算法必须包含在同一天之内(比如00:00~23:00)和跨天(比如22:00~第二天的21:00)想来想去想不到好的算法,用C51。。。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-1-9 07:24:57 来自手机 | 显示全部楼层
我在一个圆上取了两个点,问你知道我要圆上哪段弧?

出0入0汤圆

发表于 2014-1-9 08:23:15 | 显示全部楼层
03:00 是哪天的。  真晕了。

出0入0汤圆

发表于 2014-1-9 10:06:02 | 显示全部楼层
加日期判断

出0入0汤圆

发表于 2014-1-9 10:28:38 | 显示全部楼层
时间来源是啥,要是方便得到UTC秒时间,直接比大小就好。

出0入0汤圆

 楼主| 发表于 2014-1-9 12:50:47 | 显示全部楼层
本帖最后由 lswhome 于 2014-1-9 12:54 编辑

C51,时间来源是时钟芯片,判断某一时刻是否在某一时间段之内,精确到分即可,但算法必须包含时间段在同一天或者跨一天,但时间段不超过24小时。。。百度查了查,高级的语言直接就有相关的函数,非常简单,可是C51没有啊,只能自己算。。。脑子笨,虽然问题昨天晚上已经解决了,但感觉我的算法超级笨。。
算法如下:
bit Time_of_Times(UINT8 Now_h,UINT8 Now_m,UINT8 Start_h,UINT8 Start_m,UINT8 End_h,UINT8 End_m);//判断某一时间是否在某一时间段内 返回1=在,0=不在
bit Time_of_Times1(UINT8 Now_h,UINT8 Now_m,UINT8 Start_h,UINT8 Start_m,UINT8 End_h,UINT8 End_m);//判断某一时间是否在同一天的某一时间段内 返回1=在,0=不在


//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
bit Time_of_Times(UINT8 Now_h,UINT8 Now_m,UINT8 Start_h,UINT8 Start_m,UINT8 End_h,UINT8 End_m)//判断某一时间是否在某一时间段内 返回1=在,0=不在
{
       
        if(End_h>=Start_h)//先判断结束时间是否大于或者等于起始时间,如果是,则肯定在同一天,否则就跨天了
        {//如果是在同一天
                return(Time_of_Times1(Now_h,Now_m,Start_h,Start_m,End_h,End_m));   //例: Start=00:00 Now=23:26 End=23:59
        }
        else
        {//如果跨天了,返回取反的值
                return(!Time_of_Times1(Now_h,Now_m,End_h,End_m,Start_h,Start_m));  //例: Start=12:30 Now=8:30 End=08:00
        }
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
bit Time_of_Times1(UINT8 Now_h,UINT8 Now_m,UINT8 Start_h,UINT8 Start_m,UINT8 End_h,UINT8 End_m)//判断某一时间是否在同一天的某一时间段内         返回1=在,0=不在
{
        bit In;//=1在区间内,0=不在区间内

        if(Now_h==Start_h && Now_m>=Start_m && Now_h==End_h && Now_m<End_m)//时间段在同一个小时之内的情况         例:1:10~1:50  Now=1:30
                In=1;//那么在
        else
                In=0;//否则不在

        if(In==0)
        {
                if(Now_h==Start_h && Now_m>=Start_m && Now_h<End_h)//如果不在以上时间段内,但是在起始的小时内,又小于结束的时范围内  例:1:10~2:50 Now=1:30
                        In=1;//
                else
                        In=0;
        }

        if(In==0)
        {
                if(Now_h>Start_h && Now_h <End_h)//同上,大于起始的小时,又小于结束的小时 例:1:10~3:30 Now=2:20
                        In=1;
                else
                        In=0;
        }

        if(In==0)
        {
                if(Now_h>Start_h && Now_h==End_h && Now_m<End_m)//同上,大于起始的小时,但等于结束的小时 并且小于结束的分钟 例:1:10~3:30 Now=3:20
                        In=1;
                else
                        In=0;
        }

        return(In);//返回值
}


调用:
Time_of_Times(12,23,23,45,15,30);
返回1

运行结果达到了要求,但算法感觉很土,各位给精简精简呗。。。

出0入0汤圆

 楼主| 发表于 2014-1-9 12:55:57 | 显示全部楼层
zyw19987 发表于 2014-1-9 07:24
我在一个圆上取了两个点,问你知道我要圆上哪段弧?

谢谢,感觉我的算法和你的圆上取段类似。。。

出0入0汤圆

发表于 2014-1-9 13:54:20 | 显示全部楼层
zyw19987 发表于 2014-1-9 07:24
我在一个圆上取了两个点,问你知道我要圆上哪段弧?

当然可以知道 从A点到B点 如果A大于B是一种情况 如果A小于B又是一种情况

出0入0汤圆

发表于 2014-1-9 14:05:59 | 显示全部楼层
先把你的时间转换成分或秒
按照你的2个例子:
Start_t = 00:00 Now_t = 23:26 End_t = 23:59
Start_t = 12:30 Now_t = 8:30   End_t = 08:00

转换成下面的:
Start_m = 0    Now_m = 1406 End_m = 1439
Start_m = 750 Now_m = 510  End_m = 480

return Now_m >= Start_m && Now_m <= End_m

出0入0汤圆

发表于 2014-1-9 14:42:44 | 显示全部楼层
沧海清风 发表于 2014-1-9 13:54
当然可以知道 从A点到B点 如果A大于B是一种情况 如果A小于B又是一种情况

只有时分秒,你做给我看看。A(sin30°,cos30°)  B(sin200°,cos200°) 在单位圆上知道这两点就能确定一条弧?

出0入0汤圆

发表于 2014-1-9 15:11:33 | 显示全部楼层
先把日期时间转换成标准时间:
构造tm,调用mktime得到秒计数值;另外从秒计数值到日期是使用localtime
这两个函数可以到linux源码里扣……VC的CRT函数里也有,安装时勾选上就能得到

出0入0汤圆

 楼主| 发表于 2014-1-9 18:00:25 | 显示全部楼层
沧海清风 发表于 2014-1-9 14:05
先把你的时间转换成分或秒
按照你的2个例子:
Start_t = 00:00 Now_t = 23:26 End_t = 23:59

果然是大神,我刚开始考虑这么计算,换算成秒,但是一天内的秒数超出了65535,得用32位的,想来想去还是算了,哈哈。。。结果弄了个这么费劲的算法。。。得不偿失啊。。。。谢谢指点!!!

出0入0汤圆

 楼主| 发表于 2014-1-9 23:59:42 | 显示全部楼层
本帖最后由 lswhome 于 2014-1-10 01:24 编辑

沧海清风:
先把你的时间转换成分或秒
按照你的2个例子:
Start_t = 00:00 Now_t = 23:26 End_t = 23:59
Start_t = 12:30 Now_t = 8:30   End_t = 08:00

转换成下面的:
Start_m = 0    Now_m = 1406 End_m = 1439
Start_m = 750 Now_m = 510  End_m = 480

return Now_m >= Start_m && Now_m <= End_m

不好意思,你的算法部分是能够算出来的,就是在同一天的情况下或者不在同一天,但当前时间和结束时间在同一天的时候,结果是正确的,但是有一种跨天的情况,就会计算错误了
比如: Start_t = 12:30 Now_t = 13:30   End_t = 08:00(正确的话应该是返回1)

Start_m = 750 Now_m = 810  End_m = 480

那么
return( 810>=750 && 810<=480)等效return(1 && 0)因此返回0

呵呵,所以,我给改成这样了,理论上应该没问题了
        UINT16 N,S,E;

        N=Now_h*60+Now_m;//当前时间                           N=12:20=740
        S=Start_h*60+Start_m;//起始时间                   S=12:30=750
        E=End_h*60+End_m;//结束时间                           E=8:00=480

        if(E>=S)//如果在同一天
                return(N>=S && N<=E);//同一天的情况
        else
                return(!( N>=E && N<=S));//跨天的情况

非常感谢您的思路,很牛X的算法!!!

出0入0汤圆

发表于 2014-1-10 00:10:50 | 显示全部楼层
我没有仔细看各位高手的回复,说说我的想法。

你的问题是给定
起始日期第d1天,起始时间h1:m1,和
结束日期第d2天,结束时间h2:m2。
求第d天h时m分是否在上述时间段内。

以0天0时0分为基准,
计算起始日期距离基准的分钟数t1=d1*1440+h1*60+m1*1
计算结束日期距离基准的分钟数t2=d2*1440+h2*60+m2*1
计算给定时间距离基准的分钟数t =d*1440+h*60+m*1

接下来你只要判断条件((t1 <= t) && (t <= t2))就能知道是否在这个时间段内

很简单的,也不需要32位变量。
希望能帮到你。

出0入0汤圆

发表于 2014-1-10 08:19:05 | 显示全部楼层
顶14楼,简洁

出0入8汤圆

发表于 2014-1-10 10:21:40 来自手机 | 显示全部楼层
14楼的算法用三个字概括,就是 时间戳
看过无数的算闰年,算星期,算时间的代码
基本上没有超越mktime的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 04:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表