Implemented problems 11-12, improved problem 10 runtime using dynamic programming

This commit is contained in:
Egor 2024-04-18 03:14:34 +03:00
parent 4357ce4200
commit 7fbad410b1
3 changed files with 48 additions and 94 deletions

View file

@ -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];
}

View 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;
}

View 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();
}