この関数は、最初に必要な数の空白文字を破棄します。最初の非空白文字が見つかりました。次に、この文字から開始して、オプションの最初のプラス記号またはマイナス記号の後にできるだけ多くの数字を取り、それらを数値として解釈します。
文字列には、を形成する文字の後に追加の文字を含めることができます。整数。無視され、この関数の動作に影響を与えません。
str内の空白以外の文字の最初のシーケンスが有効な整数でない場合、またはそのようなシーケンスが存在しない場合は、 strが空であるか、空白文字のみが含まれている場合、変換は実行されません。
有効な変換を実行できなかった場合、ゼロ値が返されます。正しい値が表現可能な値の範囲外の場合、INT_MAX(2147483647)またはINT_MIN(-2147483648)が返されます。
わからない整数オーバーフローに対するチェックについてですが、実装は次のとおりです。
public int myAtoi(String str) { int i = 0; while (i < str.length() && Character.isWhitespace(str.charAt(i))) { ++i; } if (i == str.length()) { return 0; } boolean isNegative = false; if (str.charAt(i) == "+" || str.charAt(i) == "-") { isNegative = str.charAt(i) == "-"; ++i; } int result = 0; while (i < str.length() && Character.isDigit(str.charAt(i))) { try { result = Math.multiplyExact(result, 10); result = Math.addExact(result, Character.getNumericValue(str.charAt(i))); } catch (ArithmeticException e) { return isNegative ? Integer.MIN_VALUE : Integer.MAX_VALUE; } ++i; } if (isNegative) { result = -result; } return result; }
回答
全体として、これは「多くの重要な詳細において非常に優れた実装です。
Character.isDigit()
とCharacter.getNumericValue()
メソッドは見栄えがします。
オーバーフロー条件を処理するMath.*
メソッドも優れています。
わかりません。意図した場合でも、32ビット符号付き整数システム(Javaだけでなく)であいまいなエッジケースを正しく処理します。ここで、Integer.MIN_VALUE
は- Integer.MAX_VALUE
…そしてあなたのコードは実際にテキスト “-2147483648″の正確な入力のためにそれを正しくします
それで、あなたはあなたのコードに良い詳細を持っています…そして壊れたエッジケースは見当たりません。
私の唯一の推奨事項は、ステートマシンが物事を単純化する可能性があることです…ループが1つだけです…..しかし、ステートマシンも少し厄介かもしれませんが、長期的には…
public static int rlAtoi(String str) { boolean started = false; boolean negative = false; int result = 0; try { for (char c : str.toCharArray()) { if (!started && Character.isWhitespace(c)) { // great, ignore it. } else if (!started && (c == "+" || c == "-")) { // great, a sign negative = c == "-"; started = true; } else if (Character.isDigit(c)) { result = Math.multiplyExact(result, 10); result = Math.addExact(result, Character.getNumericValue(c)); started = true; } else { // done.... break; } } } catch (ArithmeticException e) { return negative ? Integer.MIN_VALUE : Integer.MAX_VALUE; } return negative ? -result : result; }
生のパフォーマンスベンチマークでは、ソリューションは(わずかに)高速になると思いますが、小さいよりも読みやすさを優先します。パフォーマンスが非常に重要でない限り、パフォーマンスは段階的に向上します。
コメント
- + 1ステートマシンの場合、これははるかに簡単で、ほとんどの場合、より高速で、はるかに高速です。デバッグ/拡張が簡単です。
回答
「-」文字のテストが重複しています。書き直します
boolean isNegative = false; if (str.charAt(i) == "+" || str.charAt(i) == "-") { isNegative = str.charAt(i) == "-"; ++i; }
as
boolean isNegative = false; if (str.charAt(i) == "-") { isNegative= true; ++i; } else if (str.charAt(i) == "+") ++i;
16進数のサポートも追加します
コメント
-
switch
ブロックもここでうまく機能します。 - ああ、その'は本当です。フォールスルーのある
switch
はおそらく重複が最も少ないでしょう。