我正试图解决这个页面上描述的“最好之前”的Spotify难题。基本上,输入由斜杠分隔的三个整数(例如11/3/4),您应该以2011-03-04格式生成尽可能早的输出。如果不可能出现日期,则应该返回原来的字符串,后面跟着“是非法的”。
下面我的解决方案的想法是从我在github中发现的一个相同问题的Python解决方案中借用来的。当我提交这个Python代码时,它就被接受了。不熟悉Python,这是我最好的尝试,不使用任何Calendar函数,就像在这里发布在堆栈溢出处的这解决方案一样。
然而,当我提交我的解决方案时,我会得到“错误的答案”作为回应。尽管我可能会尝试,但在这段代码中找不到任何错误。我觉得我已经尝试过每一个可能的输入组合,所有的输出结果都是正确的。有人知道我可能错过了什么吗?
由于我对一般编程还比较陌生,所以如果您愿意的话,也可以就如何改进代码提供建议。我敢肯定这看上去很下流。谢谢!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class DateProggy3 {
static int var1, var2, var3;
static int slashPosition1, slashPosition2;
static String yearString, monthString, dayString;
public static void main(String[] args) throws IOException {
String dateInput = readDate();
splitInputToInts(dateInput);
Integer[] dateArray = {var1, var2, var3};
Arrays.sort(dateArray);
Integer bestDate[] = getBestDate(dateArray, dateInput);
convertDate(bestDate);
printDate(bestDate);
}
public static String readDate() throws IOException {
BufferedReader stdin = new BufferedReader
(new InputStreamReader(System.in));
String dateInput;
dateInput = stdin.readLine();
return dateInput;
}
public static void splitInputToInts(String dateInput) {
try {
slashPosition1 = dateInput.indexOf('/');
slashPosition2 = dateInput.lastIndexOf('/');
var1 = Integer.parseInt(dateInput.substring(0, slashPosition1));
var2 = Integer.parseInt(dateInput.substring(slashPosition1+1, slashPosition2));
var3 = Integer.parseInt(dateInput.substring(slashPosition2+1, dateInput.length()));
}catch (StringIndexOutOfBoundsException e){
illegal(dateInput);
}catch (NumberFormatException e){
illegal(dateInput);
}
}
public static void illegal(String dateInput){
System.out.println(dateInput + " is illegal");
System.exit(0);
}
public static Integer[] getBestDate(Integer[] dateArray, String dateInput){
var1 = dateArray[0];
var2 = dateArray[1];
var3 = dateArray[2];
if (testDate(var1, var2, var3)){
Integer[] bestDate = {var1, var2, var3};
return bestDate;
}
else if (testDate(var1, var3, var2)){
Integer[] bestDate = {var1, var3, var2};
return bestDate;
}
else if (testDate(var2, var1, var3)){
Integer[] bestDate = {var2, var1, var3};
return bestDate;
}
else if (testDate(var2, var3, var1)){
Integer[] bestDate = {var2, var3, var1};
return bestDate;
}
else if (testDate(var3, var1, var2)){
Integer[] bestDate = {var3, var1, var2};
return bestDate;
}
else if (testDate(var3, var2, var1)){
Integer[] bestDate = {var3, var2, var1};
return bestDate;
}else{
illegal(dateInput);
}
Integer[] bestDate = {var1, var2, var3};
return bestDate;
}
public static boolean testDate(int year, int month, int day){
boolean leapYear = false;
boolean dateOK;
if (year > 100 && year < 2000){
return dateOK = false;
}
if (year < 1000){
year+=2000;
}
if (year < 0){
return dateOK = false;
}
if (year % 4 == 0) {
if (year % 100 == 0 && year % 400 != 0) {
leapYear = false;
}
leapYear = true;
}else{
leapYear = false;
}
if (month > 12 || month < 1){
return dateOK = false;
}
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (day > 31 || day < 1){
return dateOK = false;
}
break;
case 4:
case 6:
case 9:
case 11:
if (day > 30 || day < 1){
return dateOK = false;
}
break;
case 2:
int maxDay;
if (leapYear){
maxDay = 29;
}else{
maxDay = 28;
}
if (day > maxDay || day < 1){
return dateOK = false;
}
}
return dateOK = true;
}
public static void convertDate(Integer[] dateArray){
if (dateArray[0] < 1000){
dateArray[0]+=2000;
}
yearString = String.valueOf(dateArray[0]);
if (dateArray[1] < 10){
monthString = "0" + dateArray[1];
}else{
monthString = String.valueOf(dateArray[1]);
}
if (dateArray[2] < 10){
dayString = "0" + dateArray[2];
}else{
dayString = String.valueOf(dateArray[2]);
}
}
public static void printDate(Integer[] dateArray){
System.out.println(yearString + "-" + monthString +"-" + dayString);
}
}我是那个问这个问题的人,但似乎不能再对答案进行评论和回复了,因为我注册了堆栈溢出,丢失了原来的cookie或其他东西。
不管怎样,谢谢你的回答。我修正了闰年的问题,现在我的答案终于被接受了!
关于getBestDate()方法中最后两行的问题。我把它们放在那里仅仅是因为Eclipse给出了错误“此方法必须返回Integer[]类型的结果”。它似乎并不满足于将所有返回都放在if括号中。有办法绕过这件事吗?谢谢。
发布于 2011-09-11 19:33:50
一个bug:它接受2100/02/29。2100年不是闰年,所以没有2011/02/29年度。
如果我是您,我将使用SimpleDateFormat进行解析和验证(提示:lenient解析)。它更简单,更直观,代码更容易阅读。(不要重新发明车轮)
上面还有其他的想法。
不必要的作业:返回dateOK = false;
只要带着false回来
return false;(在您的情况下,dataOK变量是不必要的。)
public static void illegal(String dateInput){
System.out.println(dateInput + " is illegal");
System.exit(0);
}抛出异常而不是System.exit()。
在getBestDate()方法中,最后两行从不运行。它们是死代码(因为illegal()调用System.exit()):
}else{
illegal(dateInput);
}
Integer[] bestDate = {var1, var2, var3};
return bestDate;如果可能的话,避免静态方法和字段。最后,学习如何编写单元测试是一个很好的问题。
发布于 2011-09-11 11:07:33
你的“年度”处理有问题。拼图里写着
给定一个可能不明确的日期" A / B /C",其中A、B、C是0到2999之间的整数,在2000年1月1日至12月31日之间输出最早的法定日期,2999 (包括)使用它们作为日期、月份和年份(但不一定按该顺序)。
但是,当我在您的程序中输入1000到2000之间的年份时,它会逐字报告它们,即使它们不是有效的输出。
https://stackoverflow.com/questions/7377645
复制相似问题