查找模拟时钟中时针和分针之间的角度

发布于 2024-08-31 03:35:58 字数 162 浏览 10 评论 0原文

最近我被问到这样一个面试问题:

给定一个 12 小时模拟时钟,计算时针和分针之间较小角度的度数。尽可能精确。

我想知道最简单、最易读、最精确的算法是什么。欢迎使用任何语言的解决方案(但如果您认为有必要,请稍微解释一下)。

I was given this interview question recently:

Given a 12-hour analog clock, compute in degree the smaller angle between the hour and minute hands. Be as precise as you can.

I'm wondering what's the simplest, most readable, most precise algorithm is. Solution in any language is welcome (but do explain it a bit if you think it's necessary).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

农村范ル 2024-09-07 03:35:59

该问题被称为“时钟角度问题”,我们需要找到时钟之间的角度模拟时钟在特定时间的指针(小时和分钟)。

C 编程语言的解决方案。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<inttypes.h>
#include<assert.h>

#define STRING_LENGTH 6

double angle_between_hour_min_hand(char[]);

int main(void) {
    uint8_t test;
    printf("Enter the number of test cases\n");
    scanf("%"SCNu8,&test);
    assert(test>0);
    while(test--) {
        char time_digital[STRING_LENGTH];
        printf("Enter the time\n");
        scanf("%s",time_digital);
        double angle_between_hands_deg = angle_between_hour_min_hand(time_digital);
        abs(angle_between_hands_deg) < angle_between_hands_deg ? printf("%0.1f\n",angle_between_hands_deg) : printf("%d\n",abs(angle_between_hands_deg));
    }
    return 0;
}

double angle_between_hour_min_hand(char time_digital[]) {
    uint8_t hr,min;
    double hr_angle_deg,min_angle_deg,angle_between_hands_deg;
    char*buffer = calloc(sizeof(char),STRING_LENGTH);
    if(buffer) {
        snprintf(buffer,STRING_LENGTH,"%s",time_digital);
        hr = atoi(__strtok_r(buffer,":",&buffer));
        min = atoi(__strtok_r(NULL,":",&buffer));
        buffer -= strlen(time_digital);
        free(buffer);
        hr_angle_deg = (double)(30*hr) + (double) (0.5*min);
        // printf("hr-angle: %f\n", hr_angle_deg);
        min_angle_deg = 6*min;
        // printf("min-angle: %f\n", min_angle_deg);
        angle_between_hands_deg = (hr_angle_deg > min_angle_deg) ? hr_angle_deg - min_angle_deg : min_angle_deg - hr_angle_deg;
        if(angle_between_hands_deg > 180) {
            angle_between_hands_deg = 360 - angle_between_hands_deg;
        }
    }
    else fprintf(stderr,"Memory not allocated to the buffer pointer!\n");
    return angle_between_hands_deg;
}

在你的系统中编译上面的程序,我使用的是Ubuntu 18.04 LTS Bionic Beaver,你可以使用任何安装了C编译器的系统。

gcc -Wall -g clock_angle_sol.c -o clock_angle_sol
./clock_angle_sol
Enter the time in 12-hour or 24 hour i.e (hr:min) format: 12:45
Angle: 112.00 degrees.

注释:
1. 等式 $\theta_{hr} = (30^\circ \times hour) + (0.5^\circ \times 分钟)$将为您提供 12 小时制时针所成的角度。
2. 如果要计算 24 小时制中时针所成的角度,请使用以下公式: $\theta_{hr} = (15^\circ \times 小时) + (0.25^\circ \times 分钟) $
3. 秒针对分针的旋转也有贡献,但我们忽略了它,因为贡献很小,即1/10 = 0.1。

The problem is known as a “Clock Angle Problem” where we need to find the angle between the hands (hour & minute) of an analog clock at a particular time.

Solution in C Programming Language.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<inttypes.h>
#include<assert.h>

#define STRING_LENGTH 6

double angle_between_hour_min_hand(char[]);

int main(void) {
    uint8_t test;
    printf("Enter the number of test cases\n");
    scanf("%"SCNu8,&test);
    assert(test>0);
    while(test--) {
        char time_digital[STRING_LENGTH];
        printf("Enter the time\n");
        scanf("%s",time_digital);
        double angle_between_hands_deg = angle_between_hour_min_hand(time_digital);
        abs(angle_between_hands_deg) < angle_between_hands_deg ? printf("%0.1f\n",angle_between_hands_deg) : printf("%d\n",abs(angle_between_hands_deg));
    }
    return 0;
}

double angle_between_hour_min_hand(char time_digital[]) {
    uint8_t hr,min;
    double hr_angle_deg,min_angle_deg,angle_between_hands_deg;
    char*buffer = calloc(sizeof(char),STRING_LENGTH);
    if(buffer) {
        snprintf(buffer,STRING_LENGTH,"%s",time_digital);
        hr = atoi(__strtok_r(buffer,":",&buffer));
        min = atoi(__strtok_r(NULL,":",&buffer));
        buffer -= strlen(time_digital);
        free(buffer);
        hr_angle_deg = (double)(30*hr) + (double) (0.5*min);
        // printf("hr-angle: %f\n", hr_angle_deg);
        min_angle_deg = 6*min;
        // printf("min-angle: %f\n", min_angle_deg);
        angle_between_hands_deg = (hr_angle_deg > min_angle_deg) ? hr_angle_deg - min_angle_deg : min_angle_deg - hr_angle_deg;
        if(angle_between_hands_deg > 180) {
            angle_between_hands_deg = 360 - angle_between_hands_deg;
        }
    }
    else fprintf(stderr,"Memory not allocated to the buffer pointer!\n");
    return angle_between_hands_deg;
}

Compile the above program in your system, I used Ubuntu 18.04 LTS Bionic Beaver, you can use any system which has a C compiler installed.

gcc -Wall -g clock_angle_sol.c -o clock_angle_sol
./clock_angle_sol
Enter the time in 12-hour or 24 hour i.e (hr:min) format: 12:45
Angle: 112.00 degrees.

Notes:
1. The equation $\theta_{hr} = (30^\circ \times hour) + (0.5^\circ \times minute)$will give you the angle made by hour hand in 12-hour clock.
2. If you want to calculate the angle made by hour hand in a 24-hour clock, then use the following equation: $\theta_{hr} = (15^\circ \times hour) + (0.25^\circ \times minute)$
3. Second hand also contribute to the rotation of the minute hand, but we ignored it because the contribution is insignificant i.e. 1/10 = 0.1.

仅一夜美梦 2024-09-07 03:35:59

这是一种解决方案 (C#)。这是一个非常简单的解决方案,忽略了精度。希望解决方案是不言自明的。

public static double GetAngle(int hourHand, int minuteHand)
    {
        double oneMinuteAngle = (360 / 60);
        double oneHourAngle = (360 / 12);

        double hourAngle = oneHourAngle * hourHand;
        double minuteAngle = oneMinuteAngle * minuteHand;

        return (Math.Abs(hourAngle - minuteAngle));
    }

This is one solution (C#). This is a very simple solution and ignores precision. Hope the solution is self explanatory.

public static double GetAngle(int hourHand, int minuteHand)
    {
        double oneMinuteAngle = (360 / 60);
        double oneHourAngle = (360 / 12);

        double hourAngle = oneHourAngle * hourHand;
        double minuteAngle = oneMinuteAngle * minuteHand;

        return (Math.Abs(hourAngle - minuteAngle));
    }
窝囊感情。 2024-09-07 03:35:59

不知道这样对不对。?

//m*360/60 - (h*360/24)+(m*360/(24*60)) ->
t = abs(25*m - 60*h)/4
t = min(t,360-t)

I do not know if it's right, .something like this?

//m*360/60 - (h*360/24)+(m*360/(24*60)) ->
t = abs(25*m - 60*h)/4
t = min(t,360-t)
も让我眼熟你 2024-09-07 03:35:59

求时针和分针之间的角度是

angle=(hour*5-min)*6

for finding the angle between the hour hand and the minute hand is

angle=(hour*5-min)*6
留一抹残留的笑 2024-09-07 03:35:58

事实证明,维基百科确实有最好的答案:

// h = 1..12, m = 0..59
static double angle(int h, int m) {
    double hAngle = 0.5D * (h * 60 + m);
    double mAngle = 6 * m;
    double angle = Math.abs(hAngle - mAngle);
    angle = Math.min(angle, 360 - angle);
    return angle;
}

基本上:

  • 时针以每分钟0.5度的速度移动
  • 分针以每分钟6度的速度移动每分钟

问题已解决。


并且精度不是问题,因为小数部分是 .0.5,并且在 0..360 范围内,所有这些值都可以用double精确表示。

It turns out that Wikipedia does have the best answer:

// h = 1..12, m = 0..59
static double angle(int h, int m) {
    double hAngle = 0.5D * (h * 60 + m);
    double mAngle = 6 * m;
    double angle = Math.abs(hAngle - mAngle);
    angle = Math.min(angle, 360 - angle);
    return angle;
}

Basically:

  • The hour hand moves at the rate of 0.5 degrees per minute
  • The minute hand moves at the rate of of 6 degrees per minute

Problem solved.


And precision isn't a concern because the fractional part is either .0 or .5, and in the range of 0..360, all of these values are exactly representable in double.

油饼 2024-09-07 03:35:58

为了找到时钟指针之间的角度,

30 * [HRS - (MIN/5)] + (MIN/2) 

For finding the angle between the hands of a clock is ,

30 * [HRS - (MIN/5)] + (MIN/2) 
空城旧梦 2024-09-07 03:35:58

Polygenlubricants的java代码与我的类似。假设时钟是 12 小时制而不是 24

小时制。如果是 24 小时制,那就另当别论了。另外,还有另一个假设,假设在我们计算时时钟是否停止。

一个时钟周期是360度。

  1. 分针每分钟可以走多少度? 360 / 60 = 每分钟 6 度。

  2. 时针每小时可以走多少度? 360/12 = 每小时 30 度(因为时针走得比分钟慢)

由于以“分钟”为单位更容易计算,我们可以得到

“时针每分钟可以走多少度”?

30 / 60 = 每分钟 0.5 度。

因此,如果您知道如何获得这些数字,那么问题就可以通过这个部分数学解决方案得到解决。

The java code that polygenlubricants is similar than mine. Let's assume that the clock is 12 hour instead of 24.

If it's 24 hours, then that's a different story. Also, another assumption, assume if the clock is stopped while we calculate this.

One clock cycle is 360 degree.

  1. How many degree can the minute hand run per minute? 360 / 60 = 6 degree per minute.

  2. How many degree can the hour hand run per hour? 360/12 = 30 degree per hour (since hour hand run slower than minute)

Since it's easier to calculate in the unit, "minute", let's get

"how many degree can the hour hand run per minute"?

30 / 60 = 0.5 degree per minute.

So, if you know how to get those numbers, the problem is pretty much solved with this partial mathematical solution.

鱼窥荷 2024-09-07 03:35:58

试试这个代码:

import java.util.Scanner;

class Clock{

    public static void main(String args[]){
        int hours,mins;

    System.out.println("Enter the Time(hours) : ");
        Scanner dx = new Scanner(System.in);
        hours = dx.nextInt();

    System.out.println("Enter the time(mins) : ");
        Scanner fx = new Scanner(System.in);
        mins = fx.nextInt();

    if(hours>=0 && hours<=12){

        if(mins>=0 && mins<=59){
            double hDegrees = (hours * 30) + (mins * 0.5);
                    double mDegrees = mins * 6;
                    double diff  = Math.abs(hDegrees - mDegrees);

        System.out.println("The angle between sticks is (degrees) : "+diff);
                if (diff > 180){ 

                diff = 360 - diff;
        System.out.println("The angle between sticks is (degrees) : "+diff);
                }

        }

    }

    else{
        System.out.println("Wrong input ");
    }


}

}

Try this code :

import java.util.Scanner;

class Clock{

    public static void main(String args[]){
        int hours,mins;

    System.out.println("Enter the Time(hours) : ");
        Scanner dx = new Scanner(System.in);
        hours = dx.nextInt();

    System.out.println("Enter the time(mins) : ");
        Scanner fx = new Scanner(System.in);
        mins = fx.nextInt();

    if(hours>=0 && hours<=12){

        if(mins>=0 && mins<=59){
            double hDegrees = (hours * 30) + (mins * 0.5);
                    double mDegrees = mins * 6;
                    double diff  = Math.abs(hDegrees - mDegrees);

        System.out.println("The angle between sticks is (degrees) : "+diff);
                if (diff > 180){ 

                diff = 360 - diff;
        System.out.println("The angle between sticks is (degrees) : "+diff);
                }

        }

    }

    else{
        System.out.println("Wrong input ");
    }


}

}
这个俗人 2024-09-07 03:35:58

分角(从 12 点钟开始):360 * 分钟 / 60

时角(从 12 点钟开始):360 * (小时 % 12) / 12 + 360 * (分钟 / 60) * (1 / 12)

小时和分钟之间的角度: (小时角度 - 分钟角度) % 360
通过简单的算术,这可以减少到 30 * 小时 - 5.5 * 分钟。

Minute angle (from 12 o’clock): 360 * minutes / 60

Hour angle (from 12 o’clock): 360 * (hour % 12) / 12 + 360 * (minutes / 60) * (1 / 12)

Angle between hour and minute: (hour angle - minute angle) % 360
By simple arithmetic, this reduces to 30 * hours - 5.5 * minutes.

妖妓 2024-09-07 03:35:58
    **php code for find angle via time (minutes and hour's)**

    echo calcAngle(3,70);

function calcAngle($h, $m)
{
    // validate the input
    if ($h <0 || $m < 0 || $h >12 || $m > 60)
      {
       return "Wrong input";
      }
      else {

    if ($h == 12) $h = 0;
    if ($m == 60) $m = 0;

    $hour_angle = 0.5 * ($h*60 + $m);
    $minute_angle = 6*$m;
    $angle = abs($hour_angle - $minute_angle);
    $angle = min(360-$angle, $angle);

    return $angle;
}
}
    **php code for find angle via time (minutes and hour's)**

    echo calcAngle(3,70);

function calcAngle($h, $m)
{
    // validate the input
    if ($h <0 || $m < 0 || $h >12 || $m > 60)
      {
       return "Wrong input";
      }
      else {

    if ($h == 12) $h = 0;
    if ($m == 60) $m = 0;

    $hour_angle = 0.5 * ($h*60 + $m);
    $minute_angle = 6*$m;
    $angle = abs($hour_angle - $minute_angle);
    $angle = min(360-$angle, $angle);

    return $angle;
}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文