【问题标题】:finding next leap year java寻找下一个闰年java
【发布时间】:2021-01-28 08:47:58
【问题描述】:

代码在第一年是闰年时有效,所以如果我说年份是 2004 年,它将返回 2008 年,但当起始年不是闰年时,它什么也不返回。例如,如果给定年份是 2001、2002 或 2003 年,下一个闰年将是 2004 年,我将如何输出。我知道 while 循环是有道理的,但我不知道在里面放什么。另外我只能使用基本的 java 格式,所以没有像 java.time.Year 这样的输入类

public static boolean leapYear(int year) {
  boolean isLeap = true;
  if (year % 4 == 0) {
    if (year % 100 == 0) {
      if (year % 400 == 0)
        isLeap = true;
      else
        isLeap = false;
    } else
      isLeap = true;
  } else {
    isLeap = false;
  }
  return isLeap;
}

public static int nextLeapYear(int year) {
  int nextLeap = 0;

  if (leapYear(year)) {
    nextLeap = nextLeap + 4;
  } else {
    while (!leapYear(year)) {
      nextLeap++;
    }
    nextLeap += 1;
  }
  year += nextLeap;
  return year;
}

【问题讨论】:

  • 您也可以接受自己的答案(一段时间后,我想是 12 小时)。
  • 如果这是一个练习,那是一个很好的练习。对于生产代码,我们不会也不应该自己计算闰年,而应该将其留给`Year.isLeap() 或其他好的库方法。

标签: java date for-loop while-loop leap-year


【解决方案1】:

当然,这不需要太多处理。但是,如果您想提高程序的效率,您可以考虑以下几点:

  • 所有闰年都必须能被 4 整除。但并非所有能被 4 整除的年份都是闰年。所以首先,检查不能被 4 整除。这将是 75% 的情况。在这种情况下,请返回 false
   if (year % 4 != 0) {
        return false;
   }
  • 随着您的继续,year must be divisible by 4 请确保它不是一个世纪。这将在 25% 的时间进行评估,并在 24% 的时间返回 true。
   if (year % 100 != 0) {
       return true;
   }
  • 最后,唯一没有检查的类别是年份除以 400。如果我们按逻辑到这里,那么它一定是世纪年。所以相应地返回。这将在 0.25% 的时间内评估为真。
  return year % 400 == 0;

【讨论】:

    【解决方案2】:

    您的代码以多种方式被破坏:

    1. 你说:如果给定的年份是闰年,那么下一个闰年将是 4 年后。 这是错误的。如果你传入 1896,你的算法会返回 1900,但这是错误的; 1896 年是闰年,1900 年不是。

    2. 如果您提前退出,您的 isLeapYear 代码会更容易阅读。该方法应该有很多返回语句并且缩进更少。

    3. 您的 while 循环会一遍又一遍地问同样的问题,如果您向稳定的方法提出同样的问题(并且您的 isLeapYear 方法是稳定的),您会得到相同的答案,从而导致无限循环。大概,你不想要while(!leapYear(year)),你想要while(!leapYear(year + nextLeap)),并且你不想在while循环之后再次增加nextLeap。

    4. 实际上,您的极端情况是:如果规定的年份已经是一年,则添加 4 - 根本没有必要。想一想:您可以消除 if/else 部分。您的代码将只是 nextLeap、while 循环和 return 语句。一个 3 线,如果你做得对的话。

    【讨论】:

    • 感谢您的帮助!我还在学习,所以我可以接受所有的建议。但是,我采纳了您的建议并将代码更改为 int nextLeap = 0;而(leapYear(年+ nextLeap) == false){ nextLeap++; } 年 += 下一个跳跃;回归年份;但是,虽然它在给定年份不是闰年时起作用,但当给定年份是闰年时,它并没有在下一个闰年返回给我。那么我不需要某种 if 语句吗?
    • 不,你没有。您需要更改 1 个字符.... :)
    【解决方案3】:

    编辑:我明白了耶!

    对于任何为此苦苦挣扎的人,这对我有用:)

    public static boolean leapYear(int year) {
        if(year % 4 == 0)
        {
            if( year % 100 == 0)
            {
                // year is divisible by 400, hence the year is a leap year
                if ( year % 400 == 0)
                    return true;
                else
                    return false;
            }
            else
                return true;
        }
        else
            return false;
        }
    
    
    
    public static int nextLeapYear (int year) {
        int nextLeap = 0;
             while(leapYear(year + nextLeap) == false){
                 nextLeap++;
            
             }
            
            if(leapYear(year) == true)
                nextLeap += 4;
            
            year += nextLeap;
            return year;
    
        }
    

    【讨论】:

    • 这是一个飞跃。 nextLeapYear(2096) 返回 2100,但 2100 不是闰年(leapYear(2100) 正确返回 false)。
    • 养成将大括号 ({}) 放在 return 语句和其他任何可能进入块中的任何其他单个语句操作的习惯。它将为您节省将来的调试时间。
    【解决方案4】:

    能被四整除的每一年都是闰年,除了 对于可以被 100 整除的年份,但这些百年 如果它们能被 400 整除,则它们是闰年。例如, 1700、1800 和 1900 年不是闰年,而是 1600 年和 2000个。 - United States Naval Observatory

    可以大大简化函数,leapYear如下图:

    public static boolean leapYear(int year) {
      return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }
    

    演示:

    public class Main {
        public static void main(String[] args) {
            // Test
            System.out.println(leapYear(1999));
            System.out.println(leapYear(2000));
            System.out.println(leapYear(1900));
            System.out.println(leapYear(1904));
        }
    
        public static boolean leapYear(int year) {
            return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
        }
    }
    

    输出:

    false
    true
    false
    true
    

    然后,就可以在函数nextLeapYear中使用了,如下图:

    public class Main {
        public static void main(String[] args) {
            // Test
            System.out.println(nextLeapYear(1999));
            System.out.println(nextLeapYear(2000));
            System.out.println(nextLeapYear(2001));
        }
    
        public static int nextLeapYear(int year) {
            // If year is already a leap year, return year + 4
            if (leapYear(year)) {
                return year + 4;
            }
    
            // Otherwise, keep incrementing year by one until you find a leap year
            while (!leapYear(year)) {
                year++;
            }
    
            return year;
        }
    
        public static boolean leapYear(int year) {
            return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
        }
    }
    

    输出:

    2000
    2004
    2004
    

    在生产代码中,您应该使用 OOTB (Out-Of-The-Box) 类,java.time.Year 来处理一年。

    import java.time.Year;
    
    public class Main {
        public static void main(String[] args) {
            // Test
            System.out.println(nextLeapYear(1999));
            System.out.println(nextLeapYear(2000));
            System.out.println(nextLeapYear(2001));
        }
    
        public static int nextLeapYear(int year) {
            Year yr = Year.of(year);
            // If year is already a leap year, return year + 4
            if (yr.isLeap()) {
                return yr.plusYears(4).getValue();
            }
    
            // Otherwise, keep incrementing year by one until you find a leap year
            while (!yr.isLeap()) {
                yr = yr.plusYears(1);
            }
    
            return yr.getValue();
        }
    }
    

    输出:

    2000
    2004
    2004
    

    通过 Trail: Date Time 了解有关现代日期时间 API 的更多信息。

    【讨论】:

      【解决方案5】:

      似乎很难让nextLeapYear() 100 % 正确。请允许我提出一种更简单的思考方式,我相信这也将更简单地正确编码和/或修复可能存在的任何错误。

      声明一个变量candidateLeapYear 来保存我们尚不知道是否会是year 之后的下一个闰年的年份。将其初始化为year + 1,因为我们知道下一个闰年需要严格大于year。在循环中测试candidateLeapYear 是否是闰年(使用其他方法),如果不是,则递增 1。当循环终止时,candidateLeapYear 会保留下一个闰年。退货吧。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-10
        • 2011-12-31
        • 2011-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        相关资源
        最近更新 更多