Skip to content

Commit

Permalink
String to integer (#16)
Browse files Browse the repository at this point in the history
* add problem string to integer

* add solution string to integer

* impl solution string to integer

* fix clippy
  • Loading branch information
SKTT1Ryze authored Oct 26, 2023
1 parent 999b831 commit 2295378
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions leetcode/src/problems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod longest_palindromic_substring;
pub mod longest_substring;
pub mod median_of_two_sorted_arrays;
pub mod reverse_integer;
pub mod string_to_integer;
pub mod two_sum;
pub mod zigzag_conversion;

Expand Down
14 changes: 14 additions & 0 deletions leetcode/src/problems/string_to_integer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use super::{Difficulty, Problem, Topic};

pub struct ProblemImpl;

crate::derive_problem!(
ProblemImpl,
8,
Difficulty::Medium,
Topic::Algorithms,
"String to Integer (atoi)",
"Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer \
(similar to C/C++'s atoi function).",
"String".into()
);
1 change: 1 addition & 0 deletions leetcode/src/solutions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod longest_palindromic_substring;
pub mod longest_substring;
pub mod median_of_two_sorted_arrays;
pub mod reverse_integer;
pub mod string_to_integer;
pub mod two_sum;
pub mod zigzag_conversion;

Expand Down
108 changes: 108 additions & 0 deletions leetcode/src/solutions/string_to_integer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use super::Solution;

pub struct SolutionImpl;

impl Solution for SolutionImpl {
fn name(&self) -> String {
"Solution for String to Integer".into()
}
fn problem_id(&self) -> usize {
8
}
fn location(&self) -> String {
crate::location!();
}
fn test(&self) -> anyhow::Result<()> {
let testcases = [
("42", 42),
(" -42", -42),
("4193 with words", 4193),
(" 10522545459", 2147483647),
];

for (s, expect) in testcases {
let output = Self::my_atoi(s.to_string());

if output != expect {
anyhow::bail!("test failed for s={s}, expect={expect}, output={output}");
}
}

Ok(())
}
fn benchmark(&self) -> anyhow::Result<usize> {
anyhow::bail!("TODO");
}
}

#[derive(PartialEq, PartialOrd)]
enum State {
BeforePositive,
Positive,
Digit,
}

impl SolutionImpl {
pub fn my_atoi(s: String) -> i32 {
let mut state = State::BeforePositive;
let mut positive = true;
let mut v = Vec::new();

for ch in s.chars() {
match ch {
'-' | '+' => {
if state == State::BeforePositive {
positive = ch == '+';
state = State::Positive;
} else {
break;
}
}
'0'..='9' => {
if state != State::Digit {
state = State::Digit;
}

if ch == '0' && v.is_empty() {
continue;
}

v.push(ch as i32 - 48);
}
' ' => {
if state != State::BeforePositive {
break;
}
// or ignore
}
_ => {
if state == State::Digit {
break;
} else {
return 0;
}
}
}
}

let mut acc = 0;
for (p, e) in v.into_iter().rev().enumerate() {
acc = Self::cal_overflow(acc, e, p, positive).unwrap_or(if positive {
i32::MAX
} else {
i32::MIN
});
}

acc
}
fn cal_overflow(acc: i32, e: i32, p: usize, positive: bool) -> Option<i32> {
let pow = 10_i32.checked_pow(p as u32)?;
let pow = e.checked_mul(pow)?;
if positive {
acc.checked_add(pow)
} else {
acc.checked_sub(pow)
}
}
}
3 changes: 3 additions & 0 deletions runtime/src/registration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@ pub fn register_all(handle: ContainerHandle) -> anyhow::Result<()> {
handle.register_problem(|_| problems::reverse_integer::ProblemImpl)?;
handle.register_solution(|_| solutions::reverse_integer::SolutionImpl)?;

handle.register_problem(|_| problems::string_to_integer::ProblemImpl)?;
handle.register_solution(|_| solutions::string_to_integer::SolutionImpl)?;

Ok(())
}

0 comments on commit 2295378

Please sign in to comment.