2017-08-29 76 views
0

如何递归干燥这段代码以避免月份重复。递归DRY代码,计算几个月的天数,Java

我有一个想法,把1月的基本情况,并处理其他月份递归计算dayOfYear从上个月,然后将当前月添加到它。 类似if (month == 1) { ... } else { ... dayOfYear(month-1, dayOfMonth, year) ... } correct 但我不太确定实施情况,也不知道这是否是一种准确的方法。

假设我有一个这样的阵列,其中,我可以存储所有的我的日子 INT [] monthLengths =新INT [] {31,28,31,30,...,31}

public static int dayOfYear(int month, int dayOfMonth, int year) { 
if (month == 2) { 
    dayOfMonth += 31; 
} else if (month == 3) { 
    dayOfMonth += 59; 
} else if (month == 4) { 
    dayOfMonth += 90; 
} else if (month == 5) { 
    dayOfMonth += 31 + 28 + 31 + 30; 
} else if (month == 6) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31; 
} else if (month == 7) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30; 
} else if (month == 8) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31; 
} else if (month == 9) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; 
} else if (month == 10) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; 
} else if (month == 11) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; 
} else if (month == 12) { 
    dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31; 
} 
return dayOfMonth; 

}

+0

你为什么不只是使用API​​? –

+1

“...通过递归计算...”您的代码不是递归的。 – Turing85

+1

为什么你不想仅仅创建静态数组'int [12]'并且把所有天数放在这里? –

回答

1

正如在其他的答案建议,你可以很容易避免递归只是填充年度的1天和1天的月份之间的天量阵列。 因为从复杂性来看,递归将采取O(n)和预定义的阵列算法 - O(1)

但是,如果你真的想使用递归,您可以只需填写的天量,一些准备阵列,通过month作为指标使计算数组。

例如:

public static int[] daysOfMonth = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

public int daysOfYear(int day, int month, int year) { 
    if (month == 0) { 
     return day; 
    } 
    //specific case for leap year 
    int leapOffset = 0; 
    if (month == 2) { 
     if (Year.of(year).isLeap()) { 
      leapOffset = 1; 
     } 
    } 
    return daysOfYear(day + daysOfMonth[month-1] + leapOffset, month - 1, year); 
} 

和测试:

@Test 
public void testDay() { 
    Assert.assertEquals(LocalDate.of(2015, Month.FEBRUARY, 25).getDayOfYear(), daysOfYear(25, 1, 2015)); 
    Assert.assertEquals(LocalDate.of(2014, Month.MARCH, 25).getDayOfYear(), daysOfYear(25, 2, 2014)); 
    Assert.assertEquals(LocalDate.of(2013, Month.MAY, 25).getDayOfYear(), daysOfYear(25, 4, 2013)); 
    Assert.assertEquals(LocalDate.of(2012, Month.JUNE, 25).getDayOfYear(), daysOfYear(25, 5, 2012)); 
} 
0

您可以使用数组映射月份到天数之和,然后根据年份添加偏移量。

private static int[] daysTillMonth = ... 

public static int dayOfYear(int month, int dayOfMonth, int year) { 
    return daysTillMonth[month] + dayOfMonth + month>1?yearOffset(year):0; 
} 

private int yearOffset(int year) { 
    // implement 
} 

你也可以撰写的数学方程式才算此例如:

public static int dayOfYear(int month, int dayOfMonth, int year) { 
    int n1 = (275 * month/9) 
    int n2 = ((month + 9)/12) 
    int n3 = (1 + ((year - 4 * (year/4) + 2)/3)) 
    int n = n1 - (n2 * n3) + dayOfMonth - 30 
    return n; 
} 
+0

我会尝试这种方法,你有什么想法如何按照我的约定来实现它。 “我有一个想法,把1月的基本情况,并处理其他月份递归计算dayOfYear从上个月,然后将当前的月份添加到它。“ –

0

您的代码将在几个方面失败...

二月并不总是有28天...

你需要学习使用Java为你开发的API!

在另一方面

...没有什么在你发布的代码,以递归关系......你甚至需要这样......

我的建议有云:

public static long dayOfYear(int month, int dayOfMonth, int year) { 
    return ChronoUnit.DAYS.between(LocalDate.now(), LocalDate.of(year, month, dayOfMonth)); 
} 
+0

这不是关于API,问题来自我目前正在阅读的书。 是的,你是对的,我们遇到了一个神奇的数字,与二月。 –

0

你可以初始化第二阵列:

private static int[] monthLengths = new int[] { 31, 28, 31, 30, ..., 31}; 
private static int[] monthStart = new int[12]; 
static { 
    for (int i = 1; i < monthStart.length; ++i) { 
     monthStart[i] = monthStart[i-1] + monthLength[i-1]; 
    } 
}