Мой раст становится лучше
Oct. 20th, 2022 02:46 pmЗадача: конвертация из числа в roman numerals:
Ключевое know-how: Возвращать reference'ы на &'static [u8], который на самом деле кусок будущей строки и использовать "байтовые строки" для констант (b"str_content").
Не то, чтобы это был Trait Science, но любые другие выкрутасы с String или Vec<char> были бы куда более уродливыми или неэффективными. А тут я беру и возвращаю указатели на статические строки (которые и так и так у меня в .data будут), и из них мирно собираю строку. Точнее, я собираю в [u8], которую потом копирую в String.
Возможно, вместо while можно было бы иметь итератор, но я не уверен в выполнимости этого.
Ещё одно место "думать" - в районе extend_from_slice, т.к. я могу вызывать несколько реаллоакций в процессе 'extend', а мне по-хорошему надо было бы знать длину строки с самого начала. Но это отдельная интересная задача - определить размер строки для roman numeral по числовому значению.
impl Solution {
    fn next_biggest(num: i32) -> (&'static [u8], i32) {
        match num {
            1000.. => (b"M", 1000),
            900.. => (b"CM", 900),
            500.. => (b"D", 500),
            400.. => (b"CD", 400),
            100.. => (b"C", 100),
            90.. => (b"XC", 90),
            50.. => (b"L", 50),
            40.. => (b"XL", 40),
            10.. => (b"X", 10),
            9.. => (b"IX", 9),
            5.. => (b"V", 5),
            4.. => (b"IV", 4),
            1.. => (b"I", 1),
            _ => unimplemented!("Unable to represent in Roman")
        }
    }
    pub fn int_to_roman(mut num: i32) -> String {
        let mut acc = Vec::new();
        while num > 0{
            let (rom, value) = Self::next_biggest(num);
            acc.extend_from_slice(rom);
            num -= value;
        }
        String::from_utf8(acc).unwrap()
    }
}
Ключевое know-how: Возвращать reference'ы на &'static [u8], который на самом деле кусок будущей строки и использовать "байтовые строки" для констант (b"str_content").
Не то, чтобы это был Trait Science, но любые другие выкрутасы с String или Vec<char> были бы куда более уродливыми или неэффективными. А тут я беру и возвращаю указатели на статические строки (которые и так и так у меня в .data будут), и из них мирно собираю строку. Точнее, я собираю в [u8], которую потом копирую в String.
Возможно, вместо while можно было бы иметь итератор, но я не уверен в выполнимости этого.
Ещё одно место "думать" - в районе extend_from_slice, т.к. я могу вызывать несколько реаллоакций в процессе 'extend', а мне по-хорошему надо было бы знать длину строки с самого начала. Но это отдельная интересная задача - определить размер строки для roman numeral по числовому значению.