2011-09-11 31 views
5

Tôi đang cố gắng giải quyết câu đố Spotify "tốt nhất trước" được mô tả trong số page này. Về cơ bản, với đầu vào của ba số nguyên được phân tách bằng dấu gạch chéo (ví dụ: 11/3/4), bạn sẽ tạo ra đầu ra có ngày sớm nhất có thể trong định dạng 2011-03-04. Nếu không có ngày nào có thể, nó sẽ trả về chuỗi gốc theo sau là "là bất hợp pháp".Spotify puzzle problem

Ý tưởng cho giải pháp của tôi dưới đây được mượn từ một giải pháp Python mà tôi tìm thấy cho cùng một vấn đề tại github. Khi tôi gửi mã Python này, nó được chấp nhận. Không quen thuộc với Python, đây là nỗ lực tốt nhất của tôi khi tạo một cái gì đó tương tự với Java và không sử dụng bất kỳ chức năng Lịch nào có thể được nhìn thấy trong giải pháp this được đăng ở đây tại stackoverflow.

Khi tôi gửi giải pháp của mình, tuy nhiên, tôi nhận được "Câu trả lời sai" làm câu trả lời. Hãy thử như tôi có thể, tôi không thể tìm thấy bất kỳ lỗi nào với mã này. Tôi cảm thấy như tôi đã thử mọi kết hợp đầu vào có thể có duy nhất và tất cả các kết quả đầu ra của tôi đều xuất hiện chính xác. Bất cứ ai có bất kỳ ý tưởng những gì tôi có thể bị mất tích?

Vì tôi tương đối mới đối với lập trình nói chung, vui lòng cung cấp lời khuyên về cách mã có thể được cải thiện nói chung nếu bạn muốn. Tôi chắc chắn nó có thể trông noobish. Cảm ơn!

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); 
    } 
} 

Tôi là một trong những người hỏi những câu hỏi, nhưng dường như không thể nhận xét và trả lời thường các câu trả lời nữa kể từ khi tôi đăng ký stackoverflow và mất cookie ban đầu của tôi hoặc một cái gì đó.

Dù sao, cảm ơn palacsint cho câu trả lời của bạn. Tôi đã khắc phục vấn đề năm nhuận và bây giờ câu trả lời của tôi cuối cùng đã được chấp nhận!

Câu hỏi về hai dòng cuối cùng trong phương thức getBestDate(). Tôi đặt những người ở đó chỉ vì Eclipse IDE khác cho tôi lỗi "Phương pháp này phải trả về kết quả của kiểu Integer []". Nó không có vẻ hài lòng với việc có tất cả lợi nhuận trong các dấu ngoặc đơn if. Có cách nào để khắc phục điều này? Cảm ơn.

Trả lời

1

Một lỗi: nó chấp nhận 2100/02/29. 2100 là không phải năm nhuận, vì vậy không có 2011/02/29.

Nếu tôi là bạn, tôi sẽ sử dụng SimpleDateFormat để phân tích cú pháp và xác thực (gợi ý: lenient phân tích cú pháp). Nó đơn giản hơn nhiều, trực quan và mã sẽ dễ đọc hơn. (Đừng tạo lại bánh xe)

Một số suy nghĩ khác ở trên.

Bài tập không cần thiết: ngày trở vềOK = false;

Chỉ cần trở lại với false:

return false; 

(Biến dataOK là không cần thiết trong trường hợp của bạn.)

public static void illegal(String dateInput){ 
    System.out.println(dateInput + " is illegal"); 
    System.exit(0); 
} 

Ném ngoại lệ thay vì System.exit().

Trong phương thức getBestDate() hai dòng cuối cùng không bao giờ chạy. Họ là những mã chết (vì illegal() cuộc gọi System.exit()):

}else{ 
    illegal(dateInput); 
} 

Integer[] bestDate = {var1, var2, var3}; 
return bestDate; 

Nếu đó là phương pháp tĩnh có thể tránh và các lĩnh vực. Cuối cùng, đó là một vấn đề tốt để tìm hiểu làm thế nào để viết các bài kiểm tra đơn vị.

0

Có vấn đề trong việc xử lý 'năm' của bạn. Văn bản câu đố nói

Cho một ngày có thể mơ hồ "A/B/C", trong đó A, B, C là các số nguyên giữa 0 và 2999, sản lượng ngày quy phạm pháp luật có thể sớm nhất giữa ngày 01 tháng 1 năm 2000 và Ngày 31 tháng 12, 2999 (đã bao gồm) sử dụng chúng như ngày, tháng và năm (nhưng không nhất thiết theo thứ tự đó).

Tuy nhiên, khi tôi nhập năm từ 1000 đến 2000 vào chương trình của bạn, nó sẽ báo cáo nguyên văn, mặc dù chúng không hợp lệ.

+1

Tôi cho rằng đây không phải là vấn đề vì vấn đề nêu rõ "Bạn có thể giả định rằng năm đó, khi được cho với bốn chữ số, nằm trong khoảng từ 2000 đến 2999." và "Cho một ngày có thể mơ hồ" A/B/C ', trong đó A, B, C là các số nguyên từ 0 đến 2999 ". Tuy nhiên, tôi đã cố gắng sửa lỗi này bằng cách thêm dòng "if (year> 100 && year <2000)" như bạn có thể thấy trong mã được cập nhật. Tôi vẫn nhận được câu trả lời "sai câu trả lời" mặc dù. Cảm ơn! – mattboy