c# - 如何计算范围 [a, b] 中的闰年而不在 C# 上使用循环
问题描述
假设您有a年和b年,它们是年份范围(包括在内),如何在不使用循环的情况下正确计算此范围内的闰年?(公历)
我在 C# 上写了这个,但我不认为我的代码很棒。我也使用了一个全局变量,但是大声笑,我认为有一个比这更好、更优雅的解决方案。我只是一个新手,很抱歉我问了这个愚蠢的问题。另外,我认为你不应该在这里使用 DateTime 等等。
这是我的代码:
class Program
{
public static int leap_years = 0;
static void Main()
{
do
{
int a, b;
leap_years = 0;
do Console.Write("Enter a: ");
while (!int.TryParse(Console.ReadLine(), out a) || a < 0);
do Console.Write("Enter b: ");
while (!int.TryParse(Console.ReadLine(), out b) || b < 0 || a == b || a >= b);
Console.WriteLine("Leap years: " + countLeapYears(a, b));
} while (Console.ReadKey().Key != ConsoleKey.Escape);
}
countLeapYears
在哪里
static public int countLeapYears(int a, int b)
{
if (a > b)
return leap_years;
else
{
if (a % 4 == 0)
{
if (a % 100 == 0)
{
if (a % 400 == 0)
{
Console.WriteLine("Year {0} - leap year", a);
leap_years++;
a += 4;
countLeapYears(a, b);
}
else
{
Console.WriteLine("Year {0} - not a leap year", a);
a++;
countLeapYears(a, b);
}
}
else
{
Console.WriteLine("Year {0} - leap year", a);
leap_years++;
a += 4;
countLeapYears(a, b);
}
}
else
{
Console.WriteLine("Year {0} - not a leap year", a);
a++;
countLeapYears(a, b);
}
}
return leap_years;
}
}
解决方案
好吧,我们没有 year 0
:1BC
后面跟着1AD
which破坏了乐趣。但是,如果我们只能使用AD
(正数年),您可以尝试这样的事情:
private static int countLeapYears(int from, int to) =>
(to / 4 - (from - 1) / 4) -
(to / 100 - (from - 1) / 100) +
(to / 400 - (from - 1) / 400);
让我们就朴素计算来测试它:
private static int naiveCount(int from, int to) {
int result = 0;
for (int i = from; i <= to; ++i)
if (i % 400 == 0 || i % 4 == 0 && i % 100 != 0)
result += 1;
return result;
}
...
Random gen = new Random(123);
var result = Enumerable
.Range(1, 20)
.Select(i => {
int to = gen.Next(1590, 2222);
int from = gen.Next(1590, 2222);
return (from: Math.Min(from, to), to: Math.Max(from, to));
})
.Select(test => $"{test.from} - {test.to} actual: {countLeapYears(test.from, test.to),3} expected: {naiveCount(test.from, test.to),3}");
Console.Write(string.Join(Environment.NewLine, result));
结果:
2163 - 2212 actual: 12 expected: 12
2059 - 2102 actual: 10 expected: 10
1620 - 2056 actual: 107 expected: 107
1600 - 1684 actual: 22 expected: 22
1713 - 1988 actual: 67 expected: 67
1902 - 2164 actual: 65 expected: 65
1709 - 1881 actual: 42 expected: 42
1639 - 2124 actual: 118 expected: 118
1751 - 1948 actual: 48 expected: 48
1594 - 2184 actual: 144 expected: 144
1605 - 1691 actual: 21 expected: 21
1591 - 2082 actual: 120 expected: 120
1993 - 2066 actual: 18 expected: 18
2022 - 2158 actual: 33 expected: 33
1678 - 1919 actual: 57 expected: 57
1966 - 2128 actual: 40 expected: 40
1635 - 2069 actual: 106 expected: 106
1649 - 1963 actual: 75 expected: 75
1719 - 2169 actual: 110 expected: 110
1847 - 2093 actual: 61 expected: 61
推荐阅读
- typescript - 如何在打字稿中为接受 1 个参数或 2 个参数的函数定义参数名称和类型?
- javascript - javascript formData.entries() 为空,但输入和名称已定义。如何解决?
- s4sdk - 如何使用 OAuth2SAMLBearerAssertion 将 Neo SCP 中的目标设置为 Cloud Foundry 服务?
- c++ - 如何声明具有特定大小的多维数组?
- machine-learning - 如何使用(scikit)Adaboost 分类器对大数据集进行增量训练?
- android - 当我尝试在设备上调试我的应用程序时,我的设备没有显示在 Google Chrome 中
- airflow - 如何为依赖于另一个任务的任务设置相等的priority_weight
- uart - 什么是 nRF UART 以及在 NRF52 DK 上实现 nrf UART 应用程序需要什么?
- twitter-bootstrap-3 - 我想通过给出高度在我的引导表中有一个垂直滚动条
- java - 在春季批次中覆盖Bean问题