tweet encriptar encodeuri blockquote string indexing rust

string - encriptar - Cómo indexar una cadena en Rust



encriptar url jquery (3)

El enfoque correcto para hacer este tipo de cosas en Rust no es la indexación sino la iteración . El principal problema aquí es que las cadenas de Rust están codificadas en UTF-8, una codificación de longitud variable para caracteres Unicode. Al ser de longitud variable, la posición de memoria del noveno carácter no puede determinarse sin mirar la cadena. ¡Esto también significa que acceder al enésimo carácter tiene un tiempo de ejecución de O (n)!

En este caso especial, puede iterar sobre los bytes, ya que se sabe que su cadena solo contiene los caracteres 0–9 (iterar sobre los caracteres es la solución más general pero un poco menos eficiente).

Aquí hay un código idiomático para lograr esto ( playground ):

fn is_palindrome(num: u64) -> bool { let num_string = num.to_string(); let half = num_string.len() / 2; num_string.bytes().take(half).eq(num_string.bytes().rev().take(half)) }

Pasamos a través de los bytes en la cadena tanto hacia delante ( num_string.bytes().take(half) ) como hacia atrás ( num_string.bytes().rev().take(half) ) simultáneamente; La parte .take(half) está ahí para reducir a la mitad la cantidad de trabajo realizado. Luego, simplemente comparamos un iterador con el otro para asegurarnos en cada paso que el último y el último octetos son equivalentes; Si lo son, devuelve verdadero; si no, falso

Estoy intentando indexar una cadena en Rust, pero el compilador arroja un error. Mi código (Proyecto Euler problema 4, playground ):

fn is_palindrome(num: u64) -> bool { let num_string = num.to_string(); let num_length = num_string.len(); for i in 0 .. num_length / 2 { if num_string[i] != num_string[(num_length - 1) - i] { return false; } } true }

El error:

error[E0277]: the trait bound `std::string::String: std::ops::Index<usize>` is not satisfied --> <anon>:7:12 | 7 | if num_string[i] != num_string[(num_length - 1) - i] { | ^^^^^^^^^^^^^ | = note: the type `std::string::String` cannot be indexed by `usize`

¿Hay alguna razón por String cual String no pueda ser indexada? ¿Cómo puedo acceder a los datos entonces?


Sí, la indexación en una cadena se eliminó recientemente. Esto se hace porque las cadenas Rust son UTF-8 internamente, por lo que el concepto de indexación en sí mismo es ambiguo, y las personas tienden a usarlo mal: la indexación de bytes es rápida, pero casi siempre es incorrecta: cuando su texto contiene símbolos que no son ASCII, la indexación de bytes puede Déjelo dentro de un carácter, lo cual es realmente malo si necesita procesamiento de texto, mientras que la indexación de caracteres no es gratuita porque UTF-8 es una codificación de longitud variable.

Si está seguro de que sus cadenas solo contienen caracteres ASCII solamente, puede usar el método Ascii type (usando el método to_ascii() ) o as_bytes() en &str que devuelve el segmento de bytes:

let num_string = num.to_str().as_slice(); // ... num_string.as_bytes()[i]

Si necesita indexación de caracteres, debe usar el método char_at() :

num_string.char_at(i)


Si lo que busca es algo similar a un índice, puede usar

.chars() y .nth() en una cadena.

.chars() -> Devuelve un iterador sobre los caracteres de un segmento de cadena.

.nth() -> Devuelve el elemento nth del iterador, en una Option

Ahora puedes usar lo anterior de varias maneras, por ejemplo:

let s: String = String::from("abc"); //If you are sure println!("{}", s.chars().nth(x).unwrap()); //or if not println!("{}", s.chars().nth(x).expect("message"));