2011-09-11 28 views
5

私はこのpageで説明されたSpotifyの "最高の"解答を解決しようとしています。基本的に、スラッシュ(例えば11/3/4)で区切られた3つの整数を入力すると、2011年3月4日の形式で可能な限り早い日付で出力を生成するはずです。日付が指定できない場合は、元の文字列の後ろに "is is invalid"が返されます。困惑の問題を解決する

私の解決策のアイデアは、githubという同じ問題で見つかったPythonソリューションから借りたものです。このPythonコードを提出すると、それが受け入れられます。 Pythonに慣れていない、これは、Javaと似たようなものを作る上での私の最高の試みであり、thisの解決策で見られるようなカレンダー関数を使用することなく、ここに掲載されています。

私の解決策を提出すると、回答として「間違った回答」が表示されます。試してみてください。このコードではエラーが見つかりません。私はすべての可能な入力の組み合わせを試したように感じ、すべての出力が正しく出てきます。誰かが私が何が欠けているかもしれないという考えを持っていますか?

私は一般的にプログラミングに比較的新しいので、必要に応じてコードを一般的にどのように改善できるかについてもアドバイスしてください。私はそれがnoobishに見えるかもしれないと確信しています。ありがとう!

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

私は質問を一人ですが、私はstackoverflowのように登録して、私のオリジナルのクッキーか何かを失ったので、コメントともはや答えに正常に返信するように見えることはできません。

とにかく、あなたの答えはpalacsintに感謝します。私はうるう年の問題を修正しました。そして今、私の答えはついに受け入れられました!

getBestDate()メソッドの最後の2行についての質問です。私はEclipse IDEがそうでなければ "このメソッドはInteger []"型の結果を返さなければならないという理由でそれらをそこに置きます。返品のすべてがif括弧内にあることで満足していないようです。これを回避する方法はありますか?ありがとう。

答えて

1

1つのバグ:2100/02/29を受け入れます。 2100はではなく、閏年であるため、2011/02/29は存在しません。

私があなたの場合は、解析と検証にヒント(lenient)を使用するとSimpleDateFormatとなります。はるかに簡単で直感的でコードは読みやすくなります。 (車を改造しないでください)

上記の他の考えです。

不要な割り当て: return dateOK = false;

だけfalseで返す:

return false; 

dataOK変数は、あなたの場合には不要です。)代わりにSystem.exit()

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

スロー例外を。

getBestDate()メソッドでは、最後の2行は決して実行されません。彼らは(illegal()呼び出しSystem.exit()以降)デッドコードです:

}else{ 
    illegal(dateInput); 
} 

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

それは、静的メソッドやフィールドを避けることができます場合。最後に、単体テストの作成方法を学ぶことは良い問題です。

0

「年」の処理に問題があります。パズルのテキストが出力 2000年1月1日の間に可能な限り早い法的日、

A、B、Cは0と2999の間の整数 ある可能性があいまいな日付 "A/B/C" を、考えると言うと、 2999年12月31日(日)、月(月)、および 年(必ずしもその順序である必要はありません)を使用してください。

私はあなたのプログラムに1000年から2000年の間に年を入力した場合しかし、それは彼らが有効な出力されないにもかかわらず、逐語的にそれらを報告します。

+1

「この数字は4桁の年が2000年から2999年の間であると仮定してもよい」という問題があるため、これは問題ではないはずです。 AとBとCは0と2999の間の整数である "A/B/C 'と考えられる。それにもかかわらず、更新されたコードでわかるように、 "if(year> 100 && year <2000)"行を追加することでこれを修復しようとしました。私はまだ "間違った答え"の返事を得る。ありがとう! – mattboy