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() {
|
fn main() {
|
||||||
let matcher = RegexMatcher::new(String::from(".*"));
|
println!("{}", is_match(String::from("acaabbaccbbacaabbbb"), String::from("a*.*b*.*a*aa*a*")))
|
||||||
println!("{}", matcher.match_str(String::from("abaaaddddcccd")));
|
|
||||||
println!();
|
|
||||||
println!("{}", matcher.match_str(String::from("abcd")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: improve runtime
|
pub fn is_match(s: String, p: String) -> bool {
|
||||||
pub fn is_match(s: String, p: String) -> bool { RegexMatcher::new(p).match_str(s) }
|
let (s, p) = (s.as_bytes(), p.as_bytes());
|
||||||
|
let mut dp = vec![vec![false; p.len() + 1]; s.len() + 1];
|
||||||
#[derive(Debug, Clone)]
|
dp[s.len()][p.len()] = true;
|
||||||
enum Pattern {
|
for i in (0..=s.len()).rev() {
|
||||||
ZeroOrMore(char),
|
for j in (0..p.len()).rev() {
|
||||||
SameAs(String),
|
let first_match = i < s.len() && (p[j] == b'.' || p[j] == s[i]);
|
||||||
AnyChar,
|
if j + 1 < p.len() && p[j + 1] == b'*' {
|
||||||
ZeroOrMoreAny
|
dp[i][j] = first_match && dp[i + 1][j] || dp[i][j + 2];
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
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