La fonction supprime dabord autant de caractères despaces que nécessaire jusquà le premier caractère non blanc est trouvé. Ensuite, à partir de ce caractère, prend un signe plus ou moins initial optionnel suivi du plus grand nombre possible de chiffres numériques, et les interprète comme une valeur numérique.
La chaîne peut contenir des caractères supplémentaires après ceux qui forment le nombre entier, qui sont ignorés et nont aucun effet sur le comportement de cette fonction.
Si la première séquence de caractères non blancs dans str nest pas un nombre entier valide, ou si une telle séquence nexiste pas car soit str est vide ou ne contient que des espaces, aucune conversion nest effectuée.
Si aucune conversion valide na pu être effectuée, une valeur zéro est renvoyée. Si la valeur correcte est en dehors de la plage des valeurs représentables, INT_MAX (2147483647) ou INT_MIN (-2147483648) est renvoyé.
Je ne suis pas sûr à propos de mes vérifications contre le dépassement dentier, mais voici mon implémentation:
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; }
Answer
Dans lensemble, cest « une très bonne implémentation dans un certain nombre de détails clés.
Utilisation de Character.isDigit()
et Character.getNumericValue()
sont bonnes à voir.
Les méthodes Math.*
qui gèrent les conditions de débordement sont également bonnes.
Je ne suis pas sûr si vous le vouliez, mais vous gérez également correctement un cas de bord obscur dans les systèmes dentiers signés 32 bits (pas seulement Java), où Integer.MIN_VALUE
nest pas la même chose que - Integer.MAX_VALUE
… et votre code le fait correctement pour une saisie exacte du texte « -2147483648 »
Donc, vous avez de bons détails dans votre code …. et Je ne peux pas voir de bordures cassées.
Ma seule recommandation serait quune machine à états puisse rendre les choses plus simples … avec une seule boucle ….. mais la machine à états peut être un peu compliquée aussi, même si je pense que cela fonctionne mieux dans le long terme …
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; }
Notez que dans un benchmark de performances brutes, je soupçonne que votre solution sera (légèrement) plus rapide, mais je préfère la lisibilité aux petites des gains de performances incrémentiels, sauf si les performances sont extrêmement critiques.
Commentaires
- +1 pour la machine à états, car cest beaucoup plus facile, presque toujours plus rapide et beaucoup plus facile à déboguer / étendre.
Réponse
Il y a un test en double pour le caractère « -« . Je « réécrirai
boolean isNegative = false; if (str.charAt(i) == "+" || str.charAt(i) == "-") { isNegative = str.charAt(i) == "-"; ++i; }
comme
boolean isNegative = false; if (str.charAt(i) == "-") { isNegative= true; ++i; } else if (str.charAt(i) == "+") ++i;
Jajouterais également le support de lhexadécimal nombres.
Commentaires
- Un bloc
switch
fonctionnerait également bien ici. - Ah, que ' est vrai. Un
switch
avec une transition aurait probablement le moins de duplication.