Код Java для вычисления Високосного года

Вы говорите о безразличном сравнении без учета регистра или полном нормализованном сравнении Unicode?

При тупом сравнении не будут найдены строки, которые могут быть одинаковыми, но не бинарными.

Пример:

U212B (ANGSTROM SIGN)
U0041 (LATIN CAPITAL LETTER A) + U030A (COMBINING RING ABOVE)
U00C5 (LATIN CAPITAL LETTER A WITH RING ABOVE).

Все они эквивалентны, но также имеют разные двоичные представления.

Тем не менее, Unicode Normalisation следует обязательно прочитать, особенно если вы планируете поддерживать хангыль, тайский и другие азиатские языки.

Кроме того, IBM в значительной степени запатентовала наиболее оптимизированные алгоритмы Unicode и сделала их общедоступными. Они также поддерживают реализацию: IBM ICU

34
задан Robin Green 30 December 2013 в 08:13
поделиться

5 ответов

Мне они кажутся одинаковыми, но обратите внимание, что эта строка в вашем коде имеет некоторую избыточность:

else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0))

может быть заменена на:

else if (year % 400 == 0)

Если число кратно 400, то оно автоматически также кратно 100 и 4.

редактировать: (7 лет спустя!)

Обратите внимание, что вышеупомянутое предполагает наличие предшествующего if ((year% 4 == 0) && year% 100! = 0) из исходного вопроса!

ответ cletus должен быть принятым: https://stackoverflow.com/a/1021373/8331

(я бы удалить свой ответ, но я не могу, поскольку он принят)

13
ответ дан 10 October 2019 в 03:18
поделиться

Иметь повторение в программном обеспечении почти всегда неправильно. В любой инженерной дисциплине форма должна следовать за функцией, и у вас есть три ветви для чего-то, что имеет два возможных пути - это либо високосный год, либо нет.

Механизм, который имеет тест в одной строке, не имеет этой проблемы, но в целом было бы лучше разделить тест на функцию, которая принимает int, представляющий год, и возвращает логическое значение, указывающее, является ли год високосным. Таким образом, вы можете делать с ним что-то, кроме вывода на стандартный вывод на консоли, и вам будет проще его протестировать.

В коде, который, как известно, превышает бюджет производительности, тесты обычно организуют так, чтобы они не выполнялись. избыточным и выполнять тесты в порядке, который возвращается раньше.

3
ответ дан 27 November 2019 в 15:51
поделиться

Я предлагаю вам поместить этот код в метод и создать модульный тест.

public static boolean isLeapYear(int year) {
    assert year >= 1583; // not valid before this date.
    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

В модульном тесте

assertTrue(isLeapYear(2000));
assertTrue(isLeapYear(1904));
assertFalse(isLeapYear(1900));
assertFalse(isLeapYear(1901));
24
ответ дан 27 November 2019 в 15:51
поделиться

Правильная реализация:

public static boolean isLeapYear(int year) {
  Calendar cal = Calendar.getInstance();
  cal.set(Calendar.YEAR, year);
  return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}

Но если вы собираетесь изобретать это колесо, то:

public static boolean isLeapYear(int year) {
  if (year % 4 != 0) {
    return false;
  } else if (year % 400 == 0) {
    return true;
  } else if (year % 100 == 0) {
    return false;
  } else {
    return true;
  }
}
84
ответ дан 27 November 2019 в 15:51
поделиться

Псевдокод из Википедии, переведенный на самый компактный язык Java

(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))
9
ответ дан 27 November 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: