我正在尝试解决关于hackerrank的Rust算法问题。我的回答超过了一些较大的测试用例。大约有5个人完成了它,所以我相信这是可能的,我认为他们在发布模式下编译。我缺少什么加速?
游戏的主旨是一个反击(主要是inp)有条件地减少,并且根据谁不能再减少它,选择胜利者。
use std::io;
fn main() {
let n: usize = read_one_line().
trim().parse().unwrap();
for _i in 0..n{
let inp: u64 = read_one_line().
trim().parse().unwrap();
println!("{:?}", find_winner(inp));
}
return;
}
fn find_winner(mut n: u64) -> String{
let mut win = 0;
while n>1{
if n.is_power_of_two(){
n /= 2;
}
else{
n -= n.next_power_of_two()/2;
}
win += 1;
}
let winner =
if win % 2 == 0{
String::from("Richard")
} else{
String::from("Louise")
};
winner
}
fn read_one_line() -> String{
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read");
input
}
答案 0 :(得分:2)
您的内循环可以由内置函数组合替换:
let win = if n > 0 {
n.count_ones() + n.trailing_zeros() - 1
} else {
0
};
此外,不是每次调用find_winner
时都分配字符串,
可以返回一个字符串切片:
fn find_winner(n: u64) -> &'static str {
let win = if n > 0 {
n.count_ones() + n.trailing_zeros() - 1
} else {
0
};
if win % 2 == 0 {
"Richard"
} else{
"Louise"
}
}
答案 1 :(得分:2)
避免内存分配有助于加速应用程序。
目前,read_one_line
函数正在为每次调用执行一次内存分配,如果您将String
作为&mut
参数提供,则可以避免这种情况:
fn read_one_line(input: &mut String) -> &str {
io::stdin().read_line(input).expect("Failed to read");
input
}
请注意我如何更改返回类型以返回切片(借用input
):此处进一步使用不需要修改原始字符串。
另一项改进是I / O. Rust完全是关于显式性的,这意味着io::stdin()
是原始I / O:每次调用read_line
都会触发与内核的交互。
您可以(而且应该)使用std::io::BufReader
缓冲I / O.构建一次,然后将其作为参数传递:
fn read_one_line<'a, R>(reader: &mut R, input: &'a mut String) -> &'a str
where R: io::BufRead
{
reader.read_line(input).expect("Failed to read");
input
}
注意:
R
)比指定BufReader
的确切类型更容易:)完全放弃:
fn read_one_line<'a, R>(reader: &mut R, input: &'a mut String) -> &'a str
where R: io::BufRead
{
reader.read_line(input).expect("Failed to read");
input
}
fn main() {
let mut reader = io::BufReader::new(io::stdin());
let mut input = String::new();
let n: usize = read_one_line(&mut reader, &mut input).
trim().parse().unwrap();
for _i in 0..n{
let inp: u64 = read_one_line(&mut reader, &mut input).
trim().parse().unwrap();
println!("{:?}", find_winner(inp));
}
return;
}
更大的胜利可能是I / O(甚至可能就足够了)。
不要忘记同时申请@ John的建议,这样你就可以在主循环中免费分配了!