Implemented problems 11-12, improved problem 10 runtime using dynamic programming
This commit is contained in:
parent
4357ce4200
commit
7fbad410b1
3 changed files with 48 additions and 94 deletions
|
@ -1,101 +1,20 @@
|
|||
fn main() {
|
||||
let matcher = RegexMatcher::new(String::from(".*"));
|
||||
println!("{}", matcher.match_str(String::from("abaaaddddcccd")));
|
||||
println!();
|
||||
println!("{}", matcher.match_str(String::from("abcd")));
|
||||
println!("{}", is_match(String::from("acaabbaccbbacaabbbb"), String::from("a*.*b*.*a*aa*a*")))
|
||||
}
|
||||
|
||||
// TODO: improve runtime
|
||||
pub fn is_match(s: String, p: String) -> bool { RegexMatcher::new(p).match_str(s) }
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Pattern {
|
||||
ZeroOrMore(char),
|
||||
SameAs(String),
|
||||
AnyChar,
|
||||
ZeroOrMoreAny
|
||||
}
|
||||
|
||||
|
||||
struct RegexMatcher {
|
||||
patterns: Vec<Pattern>
|
||||
}
|
||||
|
||||
impl RegexMatcher {
|
||||
fn new(p: String) -> RegexMatcher {
|
||||
let mut patterns: Vec<Pattern> = Vec::new();
|
||||
let mut buf: String = String::new();
|
||||
let mut is_zero_or_more = false;
|
||||
for c in p.chars().rev() {
|
||||
match c {
|
||||
'*' => {
|
||||
is_zero_or_more = true;
|
||||
}
|
||||
'.' => {
|
||||
if !buf.is_empty() {
|
||||
patterns.push(Pattern::SameAs(buf.clone()));
|
||||
buf.clear();
|
||||
}
|
||||
if is_zero_or_more {
|
||||
patterns.push(Pattern::ZeroOrMoreAny);
|
||||
is_zero_or_more = false;
|
||||
} else {
|
||||
patterns.push(Pattern::AnyChar);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if is_zero_or_more {
|
||||
if !buf.is_empty() {
|
||||
patterns.push(Pattern::SameAs(buf.clone()));
|
||||
buf.clear();
|
||||
}
|
||||
patterns.push(Pattern::ZeroOrMore(c));
|
||||
is_zero_or_more = false;
|
||||
} else {
|
||||
buf.insert(0, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !buf.is_empty() { patterns.push(Pattern::SameAs(buf)); }
|
||||
patterns.reverse();
|
||||
return Self { patterns };
|
||||
}
|
||||
|
||||
fn match_str(&self, s: String) -> bool { Self::match_patterns(&s, &self.patterns) }
|
||||
|
||||
fn match_patterns(s: &str, patterns: &[Pattern]) -> bool {
|
||||
if patterns.is_empty() { return s.is_empty(); }
|
||||
return match &patterns[0] {
|
||||
Pattern::SameAs(str) => {
|
||||
if str.len() > s.len() || str != &s[0..str.len()] { return false; }
|
||||
Self::match_patterns(&s[str.len()..], &patterns[1..])
|
||||
}
|
||||
Pattern::AnyChar => {
|
||||
if s.len() < 1 { return false; }
|
||||
Self::match_patterns(&s[1..], &patterns[1..])
|
||||
}
|
||||
Pattern::ZeroOrMore(char) => {
|
||||
if s.is_empty() { return Self::match_patterns(&s, &patterns[1..]); }
|
||||
let mut max_length = 0usize;
|
||||
for c in s.chars() {
|
||||
if c != *char { break; }
|
||||
max_length += 1;
|
||||
}
|
||||
for length in (0..=max_length).rev() {
|
||||
let result = Self::match_patterns(&s[length..], &patterns[1..]);
|
||||
if result { return result; }
|
||||
}
|
||||
false
|
||||
}
|
||||
Pattern::ZeroOrMoreAny => {
|
||||
if s.is_empty() { return Self::match_patterns(&s, &patterns[1..]); }
|
||||
for length in (0..=s.len()).rev() {
|
||||
let result = Self::match_patterns(&s[length..], &patterns[1..]);
|
||||
if result { return result; }
|
||||
}
|
||||
false
|
||||
pub fn is_match(s: String, p: String) -> bool {
|
||||
let (s, p) = (s.as_bytes(), p.as_bytes());
|
||||
let mut dp = vec![vec![false; p.len() + 1]; s.len() + 1];
|
||||
dp[s.len()][p.len()] = true;
|
||||
for i in (0..=s.len()).rev() {
|
||||
for j in (0..p.len()).rev() {
|
||||
let first_match = i < s.len() && (p[j] == b'.' || p[j] == s[i]);
|
||||
if j + 1 < p.len() && p[j + 1] == b'*' {
|
||||
dp[i][j] = first_match && dp[i + 1][j] || dp[i][j + 2];
|
||||
continue;
|
||||
}
|
||||
dp[i][j] = first_match && dp[i + 1][j + 1];
|
||||
}
|
||||
}
|
||||
return dp[0][0];
|
||||
}
|
||||
|
|
20
src/bin/11_container_with_most_water.rs
Normal file
20
src/bin/11_container_with_most_water.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
fn main() {
|
||||
println!("{}", max_area(vec![1,8,6,2,5,4,8,3,7]));
|
||||
}
|
||||
|
||||
pub fn max_area(height: Vec<i32>) -> i32 {
|
||||
let (mut left, mut right) = (0, height.len() - 1);
|
||||
let mut max_water = 0;
|
||||
while left < right {
|
||||
let x = (right - left) as i32; let h;
|
||||
if height[left] < height[right] {
|
||||
h = height[left];
|
||||
left += 1;
|
||||
} else {
|
||||
h = height[right];
|
||||
right -= 1;
|
||||
};
|
||||
max_water = max_water.max(h * x);
|
||||
}
|
||||
return max_water;
|
||||
}
|
15
src/bin/12_integer_to_roman.rs
Normal file
15
src/bin/12_integer_to_roman.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
fn main() {
|
||||
|
||||
}
|
||||
|
||||
// TODO: implement solution
|
||||
pub fn int_to_roman(num: i32) -> String {
|
||||
let roman_to_int = vec![
|
||||
('M', 1000), ('D', 500), ('C', 100),
|
||||
('L', 50), ('X', 10), ('V', 5), ('I', 1)
|
||||
];
|
||||
for i in 0..roman_to_int.len() {
|
||||
|
||||
}
|
||||
return String::new();
|
||||
}
|
Loading…
Reference in a new issue