this post was submitted on 23 Dec 2024
11 points (100.0% liked)

Rust

6129 readers
52 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

[email protected]

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 2 years ago
MODERATORS
 

Hello,

As I said in the previous post that I have started learning Rust and made a simple fibonacci series generator. Today I made a palindrome string checker. it's very basic. I haven't used Enum or Struct in the code since I don't think it's necessary in this simple code.

here is the code:

use std::io;

fn main() {
    let mut input = String::new();
    let stdin = io::stdin();
    stdin.read_line(&mut input).unwrap(); // we want to exit in case it couldn't read from stdin

    input = input.replace("\n", ""); // Removing newline

    let mut is_palindrome: bool = true;
    for i in 0..input.len()/2 {
        let first_char: &str = &input[i..i+1];
        let last_char: &str = &input[input.len()-i-1..input.len()-i];
        if first_char != "\n" {
            if first_char != last_char {
                is_palindrome = false;
            }
        }
    }

    println!("palindrome: {}", is_palindrome);
}
top 12 comments
sorted by: hot top controversial new old
[–] [email protected] 7 points 6 hours ago* (last edited 6 hours ago)

I didn't see it mentioned but you could remove all trailing & leading whitespace with:

input = input.trim();

Instead of using replace.

[–] [email protected] 14 points 10 hours ago (2 children)

There is a much nicer way of checking.

Rust iterators are really powerful. Try using them instead of loops, whenever you can.

Tap for solution

let is_palindrome = input.chars().eq(input.chars().rev());

As you can see, the intent is much clearer instead of indexing into the loops. Technically this does however twice as many comparisons. They can be avoided with take and half the size of the iterator.

[–] [email protected] 2 points 8 hours ago (1 children)

let is_palindrome = input.chars().eq(input.chars().rev());

wow, this is really awesome. you just made a single liner for this whole problem. I didn't know that you could do something like this since I don't know much about Rust yet.

[–] [email protected] 3 points 8 hours ago

There's so many useful methods for iterators its worth reading the doc page to familiarize yourself. Its wicked powerful: https://doc.rust-lang.org/std/iter/trait.Iterator.html

[–] FizzyOrange 4 points 10 hours ago (1 children)

You only need to check half of the string, so I think a technically optimal solution would have some take_while and maybe char_indices in there...

[–] [email protected] 5 points 10 hours ago (1 children)

That's exactly what I Hinted at in my post, though I would use take(input.size()/2). However I wouldn't be surprised if the compiler could short circuit it, but I haven't checked.

[–] FizzyOrange 6 points 9 hours ago

Oh yeah I can't read 😄

I would be extremely surprised if any compiler was smart enough to short circuit that.

I would be a little less surprised if checking the whole string was actually faster anyway though... but I would still bet against it.

[–] FizzyOrange 5 points 10 hours ago (1 children)

Aside from the better solution with iterators that Flipper mentioned, you can also:

  • Omit the type annotation for is_palindrome - it will be inferred as bool anyway
  • break; after setting is_palindrome = false
  • Use the (0..input.len()/2).all(|i| ...) iterator method instead.
[–] [email protected] 2 points 8 hours ago

Thank you for the suggestion, I will keep these in mind.

[–] BB_C 6 points 11 hours ago

Such posts are more suitable as microblogs IMHO.

Anyway, string lengths are byte lengths, and indexing strings is actually not panic-safe. This is why we have (still-nightly) char-boundary methods now.

If you want to work on characters. use .chars().count() and .chars().nth().

And character boundaries are themselves not always grapheme boundaries, which is also something that you might need to keep in mind when you start writing serious code.

With all that in mind, you should realize, for example, that probably every string reversing beginner exercise answer in every language is actually wrong. And the wrongness may actually start at the underspecified requirements 😉

[–] [email protected] 2 points 9 hours ago

That's a fun problem! Good for getting used to how to do loops in Rust.

One thing that might be interesting is to try to do it with iterators as well. You can make a really concise solution (link is a spoiler if you plan to do this yourself) using them.

[–] [email protected] 1 points 11 hours ago

Good job!

One tip, try this change:

if first_char != last_char {
    is_palindrome = false;
    break; // stop comparison
}

Best wishes in your Rust adventure!