如何查找时钟的秒针是在更大的区域还是更小的区域

时间:2015-12-14 13:11:59

标签: algorithm

我的格式为:hh:mm:ss

我必须发现,如果在给定时间内,秒针位于由时针和分针形成的较大或较小区域中?

我知道时针以每分钟0.5度的速度移动, 分针以每分钟6度的速度移动,秒针以每分钟360度的速度移动。

但我无法知道秒针在哪个区域。那我怎么能这样做呢?

Second hand within angle between hour and minute hands:
10:15:00
04:40:30

Second hand in reflex angle:
12:01:30

3 个答案:

答案 0 :(得分:10)

这个问题引起了我的兴趣所以我继续在C#编写了一个测试项目。据我所知,它必须进行测试才能确定。

这是代码:

string strTime = "10:15:00";

DateTime dt = DateTime.ParseExact(strTime, "HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);

int nHourDegrees = (360 / 12) * dt.Hour;
int nMinuteDegrees = (360 / 60) * dt.Minute;
int nSecondDegrees = (360 / 60) * dt.Second;

if (nHourDegrees > nMinuteDegrees)
{
    int nArea1 = nHourDegrees - nMinuteDegrees;
    int nArea2 = 360 - nArea1;

    bool bArea1IsBigger = (nArea1 >= nArea2);
    if (nSecondDegrees <= nHourDegrees && nSecondDegrees >= nMinuteDegrees)
    {
        //Second hand lies in area1
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the larger area");
        }
        else
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
    }
    else
    {
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
        else
        {
            Console.WriteLine("Second hand is in the larger area");
        }
    }
}
else if (nMinuteDegrees > nHourDegrees)
{
    int nArea1 = nMinuteDegrees - nHourDegrees;
    int nArea2 = 360 - nArea1;

    bool bArea1IsBigger = (nArea1 >= nArea2);
    if (nSecondDegrees <= nMinuteDegrees && nSecondDegrees >= nHourDegrees)
    {
        //Second hand lies in area1
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the larger area");
        }
        else
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
    }
    else
    {
        if (bArea1IsBigger)
        {
            Console.WriteLine("Second hand is in the smaller area");
        }
        else
        {
            Console.WriteLine("Second hand is in the larger area");
        }
    }
}
else
{
    if (nSecondDegrees == nHourDegrees)
    {
        Console.WriteLine("Second hand is on both of the other hands");
    }
    else
    {
        Console.WriteLine("Second hand is in the ONLY area");
    }
}

我们的想法是找到时针和分针之间的区域。然后检查秒针是否在此区域内。我们还将这个区域与另一个区域进行比较,然后我们可以很容易地推断出秒针是否在两者中较小或较大。

注意:可以对代码进行一些改进:

  1. 它可以显着缩短 - 我还没有这样做,因为它主要是测试/证明如何做到这一点
  2. 如果超时(即24小时不是12小时),则必须进行更改。即减去12
  3. 如果时间转到12/60/60而不是回到0,则必须手动完成
  4. 可添加常量以消除对幻数的需要
  5. 与上述类似,但360 / 12等常见计算可以移至常量
  6. 可以将其分解为单独的方法以提高可读性
  7. 可以移入辅助方法,即bool IsInLargerArea(string timeString)
  8. 当区域大小相同时需要添加大小写,目前我假设Area1更大,如果它们相等,即>=(大于或等于)
  9. 添加检查以确保straTimes数组
  10. 只有3个部分
  11. 可能还有一些我没有想过的事情

答案 1 :(得分:4)

我会选择看起来像这样的方法。你必须确定,如果较小的区域是否经过0度,然后根据你可以说解决方案。

int minDegree;
int maxDegree;
bool over360;

if (Math.abs(hourHandDegree - minuteHandDegree) < 180){
   minDegree = Math.min(hourHandDegree, minuteHandDegree);
   maxDegree = Math.max(hourHandDegree, minuteHandDegree);
   over360 = false;
} else {
   minDegree = Math.min(hourHandDegree, minuteHandDegree);
   maxDegree = Math.max(hourHandDegree, minuteHandDegree);
   over360 = true;
}

if (over360){
    if ((secondHandDegree < minDegree) && (secondHandDegree > maxDegree)){
        return true;
    } else {
        return false;
    }
} else {
    if ((secondHandDegree > minDegree) && (secondHandDegree < maxDegree)){
        return true;
    } else {
        return false;
    }
}

答案 2 :(得分:2)

此解决方案简洁,易于理解,并允许12小时或24小时输入。

使用弧度时更容易想象。

以下是R,但希望能够轻松阅读。注意%%是模运算符。

which_region <- function(s){

  # number of seconds elapsed in day (i.e., since midnight)
  sec <- as.numeric(as.POSIXct(s, tz = "GMT", format = "%H:%M:%S")) %% (12*60*60)

  # angle of each hand, clockwise from vertical, in radians
  hour_ang <- 2*pi * (sec / (12*60*60)) # hour makes a circuit every 12*60*60 sec
  min_ang  <- 2*pi * ((sec / 60^2) %% 1) # min makes a circuit every 60*60 sec 
  sec_ang  <- 2*pi * ((sec / 60) %% 1) # sec makes a circuit every 60 sec

  hour_to_min_ang <- (2*pi + min_ang - hour_ang) %% (2*pi)
  min_to_hr_ang <- (2*pi + hour_ang - min_ang) %% (2*pi)

  if(hour_to_min_ang < min_to_hr_ang){
    return(ifelse(sec_ang > hour_ang & sec_ang < min_ang,
           "Smaller Area","Larger Area") )
  } else if(min_to_hr_ang < hour_to_min_ang){
    return(ifelse(sec_ang > min_ang & sec_ang < hour_ang,
           "Smaller Area","Larger Area") )
  } else return("Equal")
}  

which_region("06:00:00") # Equal
which_region("01:10:00") # Larger Area
which_region("01:20:15") # Smaller Area
which_region("05:10:20") # Smaller Area
which_region("12:00:00") # Equal
which_region("21:55:50") # Smaller Area
which_region("10:55:15 PM") # Larger Area