Cells
Cells

Reputation: 23

Use the `replacen` to replace the string with the original variable

I tried assigning the original magazine variable with the replaced characters, but it doesn't work.

fn can_construct(ransom_note: String, magazine: String) -> bool {
    let ransom_arr: Vec<char> = ransom_note.chars().collect();
    let mut magazine = magazine.as_str();
    for index in 0..ransom_arr.len() {
        let original_length = &magazine.len();
        let mut new_str = &magazine.replacen(ransom_arr[index], "", 1);
        if &new_str.len() == original_length {
            return false;
        }
        magazine = new_str.as_mut_str();
    }
    true
}

I don't understand why it fails.

let original_length = &magazine.len();
                       -------------- borrow later used here
let mut new_str = &magazine.replacen(ransom_arr[index], "", 1);
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
...
}
- temporary value is freed at the end of this statement

= note: consider using a `let` binding to create a longer lived value

Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.

Each letter in magazine can only be used once in ransomNote.


The above are the corresponding rules

Example:

Input: ransomNote = "aa", magazine = "ab"

Output: false

Upvotes: 0

Views: 106

Answers (1)

Dogbert
Dogbert

Reputation: 222040

The problem is that replacen returns a new String and you're taking and storing a reference to it. The String itself will be dropped at the end of the block but you're storing it in a variable that lives for longer than that. You can instead store the String value:

fn can_construct(ransom_note: String, mut magazine: String) -> bool {
    let ransom_arr: Vec<char> = ransom_note.chars().collect();
    for index in 0..ransom_arr.len() {
        let original_length = magazine.len();
        let mut new_str = magazine.replacen(ransom_arr[index], "", 1);
        if new_str.len() == original_length {
            return false;
        }
        magazine = new_str;
    }
    true
}

This compiles but since you haven't given example inputs/outputs, I couldn't test to see if it works as you expect.

This can be simplified further using iterators:

fn can_construct(ransom_note: String, mut magazine: String) -> bool {
    for char in ransom_note.chars() {
        let original_length = magazine.len();
        let mut new_str = magazine.replacen(char, "", 1);
        if new_str.len() == original_length {
            return false;
        }
        magazine = new_str;
    }
    true
}

Both these solutions are O(n^2) as string replace is an O(n) operation. If I understand the objective correctly, there's a O(n) solution possible using a HashMap.

Upvotes: 2

Related Questions