Есть ли что-нибудь упрощенное Java для поиска дат палиндомов между 0000 и 9999? - PullRequest
0 голосов
/ 04 февраля 2020
import java.util.Arrays;

public class PalindromeDates {

    static final int STARTINGYEAR = 0000;
    static final int ENDINGYEAR = 9999;

    public static void main(String[] args) {


        int year, month, date;
        int dateArray[];
        boolean flag;

        System.out.println("    Date   -->       Array Format\n");

        for (year = STARTINGYEAR; year <= ENDINGYEAR; year++) {
            for (month = 01; month <= 12; month++) {
                for (date = 1; date <= 31; date++) {

                    if (checkValidDate(year, date, month)) {
                        dateArray = createDateArray(date, month, year);
                        flag = checkPalindrome(dateArray);
                        if (flag) {
                            System.out.print(year + "." + month + "." + date + "  -->  ");
                            System.out.println(Arrays.toString(dateArray));
                        }
                    }
                }
            }
        }
    }

    public static int[] createDateArray(int date, int month, int year) { //Inserting the whole date to an array

        int dateArray[] = new int[8];

        dateArray[0] = year / 1000;
        year = year % 1000;
        dateArray[1] = year / 100;
        year = year % 100;
        dateArray[2] = year / 10;
        dateArray[3] = year % 10;

        dateArray[4] = month / 10;
        dateArray[5] = month % 10;

        dateArray[6] = date / 10;
        dateArray[7] = date % 10;

        return dateArray;
    }

    public static boolean checkPalindrome(int dateArray[]) {

        for (int i = 0; i <= 3; i++) {
            if (dateArray[i] == dateArray[7 - i]) {
            } else {
                return false;
            }
        }
        return true;
    }

    public static boolean checkValidDate(int year, int month, int date) {

        if (month == 2 && date == 30)
            return false;

        if ((month == 2 || month == 4 || month == 6 || month == 9 || month == 11) && (date == 31)) {
            return false;
        }

        if ((month == 2) && (date == 29))
            return (checkLeapYear(year));

        return true;
    }

    public static boolean checkLeapYear(int year) {

        if (year % 4 == 0) {
            if (year % 100 == 0) {
                if (year % 400 == 0)
                    return true;
                else
                    return false;
            } else
                return true;
        } else {
            return false;
        }
    }
}

Эта программа написана мной, чтобы найти даты палиндрома с 0000 по 9999. Является ли их какая-либо упрощающая программа для этого? Какие есть модификации для этого кода? И я хочу знать, правильный ли мой код поиска високосного года.

Существует метод, называемый createDateArray(). Используется для помещения целых цифр в году, месяце, дате в массив. Есть ли простой способ сделать это?

Ответы [ 3 ]

3 голосов
/ 04 февраля 2020

Из вашего кода я делаю вывод, что дата палиндрома - это дата, которая отформатирована в формате yyyyMMdd - строка палиндрома. Например, позавчера, 2 февраля 2020 года, была дата палиндрома, потому что она отформатирована в палиндром 20200202.

Есть ли какая-нибудь упрощенная программа для этого? …

Да, есть. См. Ниже.

… И я хочу знать, верен ли мой код нахождения високосного года.

Да, это правильно. Я проверил его результат с результатом Year.of(y).isLeap() для y в диапазоне от 0 до 9999.

И вопрос, который вы не задавали: как подсказал джрук в комментарии, остерегайтесь восьмеричных чисел.

    static final int STARTINGYEAR = 0000;

Хотя это работает в этом случае, оно работает по причинам, которые, боюсь, вы не до конца понимаете. Вы получите сюрпризы, если однажды вы попробуете 0500 для 500 года и получите 320, или вы используете 0008 для 8 года и получите ошибку времени компиляции. Когда целочисленный литерал Java начинается с 0 (и имеет больше цифр после него), это восьмеричное число, а не число в десятичной системе счисления. Таким образом, в вашем коде вы должны использовать 0 для года, который вы хотите напечатать как 0000:

    static final int STARTINGYEAR = 0;

java .time

С одной стороны Андреас прав в другой ответ, что это происходит намного проще при использовании классов даты, встроенных в Java. С другой стороны, класс Calendar, использованный в этом ответе, плохо спроектирован и давно устарел. Поэтому я рекомендую не использовать его и вместо этого представить решение с использованием java .time, современного Java API даты и времени.

    List<LocalDate> palindromeDates = Arrays.stream(Month.values())
            .flatMap(m -> IntStream.rangeClosed(1, m.length(true)).mapToObj(d -> MonthDay.of(m, d)))
            .map(md -> md.atYear(reverseStringToInt(md.format(monthDayFormatter))))
            .sorted()
            .collect(Collectors.toList());

    palindromeDates.forEach(ld -> System.out.println(ld.format(dateFormatter)));

В этом коде используется несколько вспомогательных элементов:

private static DateTimeFormatter monthDayFormatter = DateTimeFormatter.ofPattern("MMdd");
private static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuuMMdd");

private static int reverseStringToInt(String s) {
    StringBuilder buf = new StringBuilder(s);
    buf.reverse();
    return Integer.parseInt(buf.toString());
}

Выдержка из вывода:

01011010
01100110
01111110
01200210
…
20111102
20200202
20211202
…
92800829
92900929

Идея алгоритма украдена из ответа Андреаса, поскольку он так хорошо продуман.

Ссылка

Oracle учебник: Дата и время объяснение, как использовать java .time.

2 голосов
/ 04 февраля 2020
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuuMMdd");
for (LocalDate d = LocalDate.of(0, 1, 1); d.isBefore(LocalDate.of(10000, 1, 1)); d = d.plusDays(1)) {
    String dateString = dateFormatter.format(d);
    if (dateString.equals(new StringBuilder(dateString).reverse().toString())) {
        System.out.println(d);
    }
}
2 голосов
/ 04 февраля 2020

Поскольку год может быть любым 4-ди git годом, здесь нет никаких ограничений, поэтому просто go для всех 366 1 MMdd значений года, поверните его и используйте как год.

1) Поскольку дата скачка 0229 в обратном порядке составляет 9220, является високосным годом, и, следовательно, действительной датой палиндрома .

В качестве кода, используя Calendar, в порядке года:

List<String> palimdromeDates = new ArrayList<>();
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"/*No DST*/));
cal.clear();
cal.set(2000/*Leap Year*/, Calendar.JANUARY, 1);
for (; cal.get(Calendar.YEAR) == 2000; cal.add(Calendar.DAY_OF_YEAR, 1)) {
    int day = cal.get(Calendar.DAY_OF_MONTH);
    int month = cal.get(Calendar.MONTH) + 1;
    int year = 0; // Calculate: year = reverse(MMdd)
    for (int i = 0, n = month * 100 + day; i < 4; i++, n /= 10)
        year = year * 10 + n % 10;
    palimdromeDates.add(String.format("%04d-%02d-%02d", year, month, day));
}
Collections.sort(palimdromeDates); // Sort by year
for (String date : palimdromeDates)
    System.out.println(date);

Обратите внимание, что этот код повторяется только 366 раз и не создает ненужных String объектов или объектов другого типа, поэтому он очень быстрый и генерирует минимальный мусор.

Вывод

0101-10-10
0110-01-10
0111-11-10
0120-02-10
0121-12-10
0130-03-10
0140-04-10
0150-05-10
0160-06-10
0170-07-10
0180-08-10
0190-09-10
0201-10-20
0210-01-20
0211-11-20
0220-02-20
0221-12-20
0230-03-20
0240-04-20
0250-05-20
0260-06-20
0270-07-20
0280-08-20
0290-09-20
0301-10-30
0310-01-30
0311-11-30
0321-12-30
0330-03-30
0340-04-30
0350-05-30
0360-06-30
0370-07-30
0380-08-30
0390-09-30
1001-10-01
1010-01-01
1011-11-01
1020-02-01
1021-12-01
1030-03-01
1040-04-01
1050-05-01
1060-06-01
1070-07-01
1080-08-01
1090-09-01
1101-10-11
1110-01-11
1111-11-11
1120-02-11
1121-12-11
1130-03-11
1140-04-11
1150-05-11
1160-06-11
1170-07-11
1180-08-11
1190-09-11
1201-10-21
1210-01-21
1211-11-21
1220-02-21
1221-12-21
1230-03-21
1240-04-21
1250-05-21
1260-06-21
1270-07-21
1280-08-21
1290-09-21
1301-10-31
1310-01-31
1321-12-31
1330-03-31
1350-05-31
1370-07-31
1380-08-31
2001-10-02
2010-01-02
2011-11-02
2020-02-02
2021-12-02
2030-03-02
2040-04-02
2050-05-02
2060-06-02
2070-07-02
2080-08-02
2090-09-02
2101-10-12
2110-01-12
2111-11-12
2120-02-12
2121-12-12
2130-03-12
2140-04-12
2150-05-12
2160-06-12
2170-07-12
2180-08-12
2190-09-12
2201-10-22
2210-01-22
2211-11-22
2220-02-22
2221-12-22
2230-03-22
2240-04-22
2250-05-22
2260-06-22
2270-07-22
2280-08-22
2290-09-22
3001-10-03
3010-01-03
3011-11-03
3020-02-03
3021-12-03
3030-03-03
3040-04-03
3050-05-03
3060-06-03
3070-07-03
3080-08-03
3090-09-03
3101-10-13
3110-01-13
3111-11-13
3120-02-13
3121-12-13
3130-03-13
3140-04-13
3150-05-13
3160-06-13
3170-07-13
3180-08-13
3190-09-13
3201-10-23
3210-01-23
3211-11-23
3220-02-23
3221-12-23
3230-03-23
3240-04-23
3250-05-23
3260-06-23
3270-07-23
3280-08-23
3290-09-23
4001-10-04
4010-01-04
4011-11-04
4020-02-04
4021-12-04
4030-03-04
4040-04-04
4050-05-04
4060-06-04
4070-07-04
4080-08-04
4090-09-04
4101-10-14
4110-01-14
4111-11-14
4120-02-14
4121-12-14
4130-03-14
4140-04-14
4150-05-14
4160-06-14
4170-07-14
4180-08-14
4190-09-14
4201-10-24
4210-01-24
4211-11-24
4220-02-24
4221-12-24
4230-03-24
4240-04-24
4250-05-24
4260-06-24
4270-07-24
4280-08-24
4290-09-24
5001-10-05
5010-01-05
5011-11-05
5020-02-05
5021-12-05
5030-03-05
5040-04-05
5050-05-05
5060-06-05
5070-07-05
5080-08-05
5090-09-05
5101-10-15
5110-01-15
5111-11-15
5120-02-15
5121-12-15
5130-03-15
5140-04-15
5150-05-15
5160-06-15
5170-07-15
5180-08-15
5190-09-15
5201-10-25
5210-01-25
5211-11-25
5220-02-25
5221-12-25
5230-03-25
5240-04-25
5250-05-25
5260-06-25
5270-07-25
5280-08-25
5290-09-25
6001-10-06
6010-01-06
6011-11-06
6020-02-06
6021-12-06
6030-03-06
6040-04-06
6050-05-06
6060-06-06
6070-07-06
6080-08-06
6090-09-06
6101-10-16
6110-01-16
6111-11-16
6120-02-16
6121-12-16
6130-03-16
6140-04-16
6150-05-16
6160-06-16
6170-07-16
6180-08-16
6190-09-16
6201-10-26
6210-01-26
6211-11-26
6220-02-26
6221-12-26
6230-03-26
6240-04-26
6250-05-26
6260-06-26
6270-07-26
6280-08-26
6290-09-26
7001-10-07
7010-01-07
7011-11-07
7020-02-07
7021-12-07
7030-03-07
7040-04-07
7050-05-07
7060-06-07
7070-07-07
7080-08-07
7090-09-07
7101-10-17
7110-01-17
7111-11-17
7120-02-17
7121-12-17
7130-03-17
7140-04-17
7150-05-17
7160-06-17
7170-07-17
7180-08-17
7190-09-17
7201-10-27
7210-01-27
7211-11-27
7220-02-27
7221-12-27
7230-03-27
7240-04-27
7250-05-27
7260-06-27
7270-07-27
7280-08-27
7290-09-27
8001-10-08
8010-01-08
8011-11-08
8020-02-08
8021-12-08
8030-03-08
8040-04-08
8050-05-08
8060-06-08
8070-07-08
8080-08-08
8090-09-08
8101-10-18
8110-01-18
8111-11-18
8120-02-18
8121-12-18
8130-03-18
8140-04-18
8150-05-18
8160-06-18
8170-07-18
8180-08-18
8190-09-18
8201-10-28
8210-01-28
8211-11-28
8220-02-28
8221-12-28
8230-03-28
8240-04-28
8250-05-28
8260-06-28
8270-07-28
8280-08-28
8290-09-28
9001-10-09
9010-01-09
9011-11-09
9020-02-09
9021-12-09
9030-03-09
9040-04-09
9050-05-09
9060-06-09
9070-07-09
9080-08-09
9090-09-09
9101-10-19
9110-01-19
9111-11-19
9120-02-19
9121-12-19
9130-03-19
9140-04-19
9150-05-19
9160-06-19
9170-07-19
9180-08-19
9190-09-19
9201-10-29
9210-01-29
9211-11-29
9220-02-29
9221-12-29
9230-03-29
9240-04-29
9250-05-29
9260-06-29
9270-07-29
9280-08-29
9290-09-29
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...