J'essaie de trouver la somme de tous les chiffres d'un nombre donné, comme 134
donne 8
.
Mon plan consiste à parcourir le nombre en le convertissant en string
à l'aide de .to_string()
, puis à utiliser .chars()
pour effectuer une itération sur le nombre. Ensuite, je veux convertir chaque char
de l'itération en un integer
et l'ajouter à une variable. Je veux obtenir la valeur finale de cette variable.
J'ai essayé d'utiliser le code ci-dessous pour convertir une char
en une integer
( Playground ):
fn main() {
let x = "123";
for y in x.chars() {
let z = y.parse::<i32>().unwrap();
println!("{}", z + 1);
}
}
Mais il en résulte cette erreur:
error: no method named `parse` found for type `char` in the current scope
--> <anon>:4:19
|
4 | let z = y.parse::<i32>().unwrap();
| ^^^^^
Comment puis-je convertir une char
en un entier?
Le code ci-dessous fait exactement ce que je veux faire ( Playground ):
fn main() {
let mut sum = 0;
let x = 123;
let x = x.to_string();
for y in x.chars() {
// converting `y` to string and then to integer
let z = (y.to_string()).parse::<i32>().unwrap();
// incrementing `sum` by `z`
sum += z;
}
println!("{}", sum);
}
mais je dois d’abord convertir char
en chaîne, puis en entier pour incrémenter sum
de z
. Existe-t-il un moyen de convertir directement char
en entier?
La méthode dont vous avez besoin est char::to_digit
. Il convertit char
en un nombre qu'il représente dans la base donnée.
Vous pouvez également utiliser Iterator::sum
pour calculer facilement la somme d’une séquence:
fn main() {
const RADIX: u32 = 10;
let x = "134";
println!("{}", x.chars().map(|c| c.to_digit(RADIX).unwrap()).sum::<u32>());
}
my_char as u32 - '0' as u32
Maintenant, il reste encore beaucoup à apprendre sur cette réponse.
Cela fonctionne parce que les codages ASCII (et donc UTF-8) ont les chiffres arabes 0 à 9 classés par ordre croissant. Vous pouvez obtenir les valeurs scalaires et les soustraire.
Cependant, que doit-il faire pour les valeurs en dehors cette plage? Que se passe-t-il si vous fournissez 'p'
? Il retourne 64. Qu'en est-il de '.'
? Cela va paniquer. Et '♥'
retournera 9781.
Les chaînes ne sont pas que des sacs d'octets. Ils sont encodés en UTF-8 et vous ne pouvez pas simplement ignorer ce fait. Chaque char
peut contenir n'importe quelle valeur scalaire Unicode.
C'est pourquoi les chaînes ne sont pas la bonne abstraction du problème.
Du point de vue de l'efficacité, l'attribution d'une chaîne semble inefficace. Rosetta Code a un exemple d'utilisation d'un itérateur qui ne fait que des opérations numériques:
struct DigitIter(usize, usize);
impl Iterator for DigitIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.0 == 0 {
None
} else {
let ret = self.0 % self.1;
self.0 /= self.1;
Some(ret)
}
}
}
fn main() {
println!("{}", DigitIter(1234, 10).sum::<usize>());
}
Une autre méthode consiste à parcourir les caractères de votre chaîne, à les convertir et à les ajouter à l'aide de fold
.
fn sum_of_string(s: &str) -> u32 {
s.chars().fold(0, |acc, c| c.to_digit(10).unwrap_or(0) + acc)
}
fn main() {
let x = "123";
println!("{}", sum_of_string(x));
}