문제

나는 일주일 범위의 날짜가 비정상적인 방식으로 저장되어 있습니다.

날짜는이 숫자 형식으로 저장됩니다 : 12150

왼쪽에서 오른쪽으로:

첫 번째 숫자는 날을 나타냅니다 : 1 = 일요일, 2 = 월요일, 3 = 화요일, .... 7 = 토요일

다음 두 자릿수는 24 시간 시스템의 시간을 나타냅니다 : 00 = 자정, 23 = 11pm

다음 두 자리는 분을 나타냅니다 : 00-59

입력 날짜와 시작 날짜 및 종료 날짜가 주어지면 입력 날짜가 시작과 종료 날짜 사이에 있는지 알아야합니다.

지금은 알고리즘이 있습니다 생각한다 시간의 100% 작동하지만 확실하지 않습니다.

어쨌든, 나는 이것을 할 수있는 더 좋고 간단한 방법이있을 것이라고 생각하며, 그 알고리즘이 무엇인지 아는 사람이 궁금했습니다.

그렇지 않은 경우 누군가 내 작업을 두 번 확인하고 실제로 유효한 경우 100%에 대해 작동하는지 확인할 수 있다면 멋질 것입니다.

내가 지금 가지고있는 것은 다음과 같습니다.

if (startDate < inputDate && 
    endDate > inputDate) {
        inRange = yes;    
}
else if (endDate < startDate) {
        if((inputDate + 72359) > startDate &&
          (inputDate + 72359) < endDate) {
          inRange = yes; 
        }
        else if((inputDate + 72359) > startDate &&
               (inputDate + 72359) < (endDate + 72359)) {
          inRange = yes;   
        }

}
도움이 되었습니까?

해결책

어때

const int MAX = 72460; // Or anything more than the highest legal value
inRange = (MAX + inputDate - startDate) % MAX < 
          (MAX + endDate - startDate) % MAX;

이것은 물론 모든 날짜가 잘 형성되었다고 가정합니다 (사양에 따라).

이것은 시작이 "후"이후의 경우를 다룹니다. (예 : 시작이 수요일이고 끝이 월요일이면 금요일이 범위에 있습니다)

보는 데 1 초가 걸릴 수 있습니다 (아마도 가독성이 가장 중요하기 때문에 좋지 않을 것입니다). 그러나 나는 그것이 효과가 있다고 생각합니다.

기본 요령은 다음과 같습니다.

Legend: 

  0: Minimum time
  M: Maximum time

  S: Start time
  1,2,3: Input Time test points
  E: End Time

The S  E => Not in range
  2  In range
  3 > E => Not in range

The S > E case
                        0                 M
  Original              -1--E----2---S--3--
  Add Max               -------------------1--E----2---S--3--
  Subtract StartDate    ------1--E----2---S--3--      
  % Max                 S--3--1--E----2----

  1  In range
  2 > E => Not in range
  3  In range

당신이 정말로 견과를 원한다면 (그리고 해독하기가 더 어려워)

const int MAX = 0x20000; 
const int MASK = 0x1FFFF;
int maxMinusStart = MAX - startDate;
inRange = (maxMinusStart + inputDate) & MASK < 
          (maxMinusStart + endDate) & MASK;

Max의 가치가 실제로 중요하지 않기 때문에 (최대 성형 된 값을 초과하는 한) 약간 더 빠르고 (약간의 경우, 약간의 거래 모듈러스 및 우리가 할 수있는), 우리는 자유롭게 선택할 수 있어야합니다. 계산을 쉽게 만듭니다.

(물론 당신은 교체 할 수 있습니다 < a <= 그것이 당신이 정말로 필요한 것인지)

다른 팁

해당 형식의 날짜에는 논리 오류가 있습니다. 월과 연도 정보가 누락되었으므로 캘린더의 날이 누락 된 것을 알 수 없습니다. EG 50755는 2009 년 3 월 12 일 목요일 일지 모르지만 정확히 일주일 전 또는 18 주 앞서있을 수도 있습니다. 그것은 당신이 100% 확신 할 수 없습니다. 어느 해당 형식의 날짜는 사이입니다 어느 다른 2 날짜.

여기 내면의 상태 if 그 이후로는 결코 사실이 될 수 없습니다 endDate < startDate:

if (endDate < startDate) {
  if((inputDate + 72359) > startDate &&
    (inputDate + 72359) < endDate) {
    // never reached
    inRange = yes; 
  }

첫 번째 부분은 항상 사실이고 두 번째 부분은 동일하기 때문에 다음은 최적이 될 수 없습니다. inputDate < endDate:

  if((inputDate + 72359) > startDate &&
     (inputDate + 72359) < (endDate + 72359))

나는 당신이 다음과 같은 것을 원한다고 생각합니다.

if (startDate < endDate)
  inRange = (startDate < inputDate) && (inputDate < endDate);
else
  inRange = (startDate < inputDate) || (inputDate < endDate);

> = 및 <= 실제로 범위에서 원한다면 사용해야합니다.

이 날짜 10000 또는 72359를 선택했다고 가정 해 봅시다. 어떻게 처리할까요? 범위에 있습니까?

또한 초기화하지 않았기 때문에 StartDate 및 EndDate에 대한 가치를 알지 못했습니다. 내가 틀렸다면 수정하십시오. 초기화되지 않은 변수는 0 또는 null 또는 ''로 시작됩니다.

그래서 나는 startDate = 10000 및 EndDate 72359를 가정합니다.

btw 왜 이런 종류의 배열 (int 또는 문자열 값으로?)을 선택하는 이유는 무엇입니까? 날짜가 아님 예 :
010000-> 날짜 1 월 1 일 00:00
312359-> DATE DATE의 3 월 23:59

그러나 그것은 당신에게 달려 있습니다 : d

내가 틀렸다면 죄송합니다. 나는 대학에서만 알고리즘 수업을 들었고 5 년 전 : D

더 나은 접근 방식은 일주일의 하루 종일 값을 시작 날짜와 관련하여 데이터를 변환하는 것입니다. 이 같은:

const int dayScale = 10000;  // scale factor for the day of the week

int NormalizeDate(int date, int startDay) 
{
    int day = (date / dayScale) - 1;  // this would be a lot easier if Sunday was 0 
    int sday = startDay - 1;  

    if (day < sday)  
        day = (day + 7 - sday) % 7;

    return ((day+1) * dayScale) + (date % dayScale);
}

int startDay = startDate / dayScale;  // isolate the day of the week

int normalizedStartDate = NormalizeDate(startDate, startDay);
int normalizedEndDate = NormalizeDate(endDate, startDay);
int normalizedInputDate = NormalizeDate(inputDate, startDay);

inRange = normalizedInputDate >= normalizedStartDate && 
          normalizedInputDate <= normalizedEndDate;

나는 이것이 서면으로 작동 할 것이라고 확신합니다. 어쨌든, 개념은 다중 비교보다 깨끗합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top