ローマンプレゼンテーションの文字列が正しいかどうかをチェックする関数を書いてみたい。彼らは、非許可の組み合わせの例たくさんある:我々は、連続して3回以上同じ文字を使用することはできませんローマ数字の妥当性を確認する(難しい)
- (私は与えられた文字列は1と3999の間の数を表すと仮定):元:IIIIは偽です。
- DDは偽( 'D' + 'D' = 500 + 500 = 1000 M
- 文字を切り捨てて直後に同じ文字を追加することはできません。例えばIXI正しいものではないIXが9の場合、9 + 1と等しくない
- 最上位の桁は、途中や最後ではなく、始まりでなければなりません。例:XM(for 1010)はfalseです。正しい。
- など...だから
は、私の考えではなく、非許可の組み合わせをチェックするよりも、私はすべての可能を書きますということでした私たちがそれらの間にない組み合わせを満たすたびに、我々は偽を返します。それが私の考えでした。私の最終的な機能は非常に長く、理解しにくいという不都合があります。
たとえば、最初に何千もあるかどうかをチェックする関数を書いた場合、関数は次の部分に移動するために現在の文字列の部分文字列に使用するインデックスを返します。その場合数百):
private static int isThousandsValid(String str){
int len = str.length();
char a1 = str.charAt(0);
char a2 = (len >= 2)? str.charAt(1) : ' ';
char a3 = (len >= 3)? str.charAt(2) : ' ';
if (a1 == 'M' && a2 == 'M' && a3 == 'M') //if we met that combinatin
return 3; //we have to move after 3 digits to meet the beginning
//of the hundred digits
else if (a1 == 'M' && a2 == 'M') //same raisoning for other combinations
return 2;
else if (a1 == 'M')
return 1;
else if (a1 == 'D' || a1 == 'C' || a1 == 'L' || a1 == 'X' || a1 == 'V' || a1 == 'I' )
return 0;
else return -1;
}
次に、私は数百、数十、単位で同じことを書いた。数百人のための例:
private static int isHundredsValid(String str){
if (str.isEmpty()) return 0;
int len = str.length();
char a1 = str.charAt(0);
char a2 = (len >= 2)? str.charAt(1) : ' ';
char a3 = (len >= 3)? str.charAt(2) : ' ';
char a4 = (len >= 4)? str.charAt(3) : ' ';
if (a1 == 'C' && a2 == 'M')
return 2;
else if (a1 == 'D' && a2 == 'C' && a3 == 'C' && a4 == 'C')
return 4;
else if (a1 == 'D' && a2 == 'C' && a3 == 'C')
return 3;
else if (a1 == 'D' && a2 == 'C')
return 2;
else if (a1 == 'D')
return 1;
else if (a1 == 'C' && a2 == 'D')
return 2;
else if (a1 == 'C' && a2 == 'C' && a3 == 'C')
return 3;
else if (a1 == 'C' && a2 == 'C')
return 2;
else if (a1 == 'C')
return 1;
else if (a1 == 'L' || a1 == 'X' || a1 == 'V' || a1 == 'I' )
return 0;
else return -1;
}
その後、私の最後の機能で、私はこれを書い:
public static boolean isValidRoman(String str){
str = str.trim(); //remove spaces
if (str.isEmpty()) return false;
int index1 = isThousandsValid(str);
String str1 = mySubstring(str, index1);
int index2 = isHundredsValid(str1);
String str2 = mySubstring(str1, index2);
int index3 = isTensValid(str2);
String str3 = mySubstring(str2, index3);
int index4 = isUnitsValid(str3);
String str4 = mySubstring(str3, index4);
if (str1.isEmpty() || str2.isEmpty() || str3.isEmpty())
return true;
if (index1 == -1 || index2 ==-1 || index3 == -1 || index4 == -1)
return false;
return str4.isEmpty(); //if we still have ANOTHER character after it terminates
}
最後に「mySubstringは、」私は私のコードをリファクタリングしてクリアするために使用だけの簡単な関数である:
private static String mySubstring(String str, int index){
if (index == -1) return str;
else
return str.substring(index);
}
私は2つの主な質問をしています: この機能はあなたのために正しいようですか?私は多くの例でテストしましたが、私は本当にわかりません(私は3999の組み合わせをすべてテストすることはできません...)
改善することは可能ですか?ちょうどそれをよりきれいにするか、またはより読みやすくするには? ローマン番号の妥当性をチェックするより簡単な方法はありますか?
は、[コードレビュー](http://codereview.stackexchange.com/)であります行く場所。 – Mephy