Toiminto hylkää ensin niin monta välilyöntiä kuin tarvitaan, kunnes ensimmäinen ei-välilyönnin merkki löytyy. Sitten tästä merkistä alkaen valinnainen alku- tai miinusmerkki, jota seuraa mahdollisimman monta numeerista numeroa, ja tulkitsee ne numeerisena arvona.
Merkkijono voi sisältää muita merkkejä niiden jälkeen, jotka muodostavat merkin integraaliluku, jotka jätetään huomiotta ja joilla ei ole vaikutusta tämän toiminnon käyttäytymiseen.
Jos str-sekvenssissä ei-tyhjätavaramerkkien ensimmäinen sekvenssi ei ole kelvollinen integraaliluku tai jos sellaista ei ole, koska str on tyhjä tai se sisältää vain välilyöntejä, muunnosta ei suoriteta.
Jos kelvollista muunnosta ei voitu suorittaa, palautetaan nolla-arvo. Jos oikea arvo on edustettavien arvojen ulkopuolella, palautetaan INT_MAX (2147483647) tai INT_MIN (-2147483648).
En ole varma tarkistuksistani kokonaislukujen ylivuotoa vastaan, mutta tässä on toteutukseni:
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; }
vastaus
Kaiken kaikkiaan tämä ”on melko hyvä toteutus useilla keskeisillä yksityiskohdilla.
Character.isDigit()
ja Character.getNumericValue()
-menetelmät ovat hyviä nähdä.
Myös Math.*
-menetelmät, jotka käsittelevät ylivuoto-olosuhteita, ovat hyviä.
En ole varma jos tarkoitit, mutta käsittelet myös hämärää reunatapausta 32-bittisissä allekirjoitetuissa kokonaislukujärjestelmissä (ei pelkästään Java), joissa Integer.MIN_VALUE
ei ole sama kuin - Integer.MAX_VALUE
… ja koodisi saa oikean kuvan tekstin ”-2147483648” tarkalle syötölle.
Joten koodissasi on hyviä tietoja …. ja En näe mitään rikkoutuneita reunatapauksia.
Ainoa suositukseni on, että valtio-kone voi tehdä asiat yksinkertaisemmiksi … yhdellä silmukalla ….. mutta myös valtion kone saattaa olla hieman sotkuinen, vaikka mielestäni se toimii paremmin pitkällä aikavälillä …
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; }
Huomaa, että raakan suorituskyvyn vertailuarvossa epäilen ratkaisusi olevan (hieman) nopeampi, mutta pidän parempana luettavuudesta kuin pienestä suorituskyvyn kasvu, paitsi jos suorituskyky on erittäin kriittinen.
Kommentit
- +1 valtion koneelle, koska tämä on paljon helpompaa, melkein aina nopeampi ja paljon helpompi virheenkorjaus / laajennus.
Vastaa
”-” -merkille on kaksoistesti. Kirjoitin uudestaan
boolean isNegative = false; if (str.charAt(i) == "+" || str.charAt(i) == "-") { isNegative = str.charAt(i) == "-"; ++i; }
nimellä
boolean isNegative = false; if (str.charAt(i) == "-") { isNegative= true; ++i; } else if (str.charAt(i) == "+") ++i;
Lisäisin myös tuen heksadesimaaleille numerot.
Kommentit
-
switch
-lohko toimisi myös tässä hyvin. - Ah, että ' on totta. all id: n sisältävällä
switch
: llä on todennäköisesti vähiten päällekkäisyyksiä.