This is an automated archive made by the Lemmit Bot.
The original was posted on /r/rust by /u/omagdy7 on 2023-08-23 17:17:55.
I am doing some leetcode and solved the same problem in both C++ and Rust and the 2 solutions are pretty much the same but the C++ solution is 100x the Rust one I am definitely doing something wrong here but can’t put my finger on it. Here are the two solutions:
C++:
class Solution {
public:
bool helper(string &s, string &t, unordered_map &mp) {
for (int i = 0; i < s.size(); i++) {
if (mp.find(s[i]) != mp.end()) {
auto tmp = mp[s[i]];
mp[s[i]] = t[i];
if (tmp != mp[s[i]]) {
return false;
}
} else {
mp[s[i]] = t[i];
}
}
return true;
}
bool isIsomorphic(string s, string t) {
if (s.size() != t.size()) return false;
unordered_map mp;
if (unordered_set(s.begin(), s.end()).size() <= unordered_set(t.begin(), t.end()).size()) {
return helper(s, t, mp);
} else {
return helper(t, s, mp);
}
}
};
Rust
use std::collections::{HashMap, HashSet};
pub fn helper(s : &String, t: &String, mp : &mut HashMap) -> bool {
for i in 0..s.len() {
if let Some(&ele) = mp.get(&s.chars().nth(i).unwrap()) {
if ele != t.chars().nth(i).unwrap() {
return false;
}
} else {
mp.insert(s.chars().nth(i).unwrap(), t.chars().nth(i).unwrap());
}
}
return true;
}
impl Solution {
pub fn is_isomorphic(s: String, t: String) -> bool {
if s.len() != t.len() {
return false;
}
let mut mp : HashMap = HashMap::new();
if s.chars().collect::>().len() < t.chars().collect::>().len() {
helper(&s, &t, &mut mp)
} else {
helper(&t, &s, &mut mp)
}
}
}
Edit: Thanks a lot guys for the all the input and tips and tricks
Rust version uses Unicode, and chars().nth() is horribly expensive and an anti-pattern. Every call to nth(i) always scans all n-1 chars first, so used in a loop it causes quadratic performance drop.
Use bytes or UTF-32 vectors of chars.
Also loops like (for i in 0…len) are the slowest type of loop in Rust. Iterators optimize better.