Files
@ f4558f3f9f5e
Branch filter:
Location: Regular-Expresso/src/main.rs
f4558f3f9f5e
4.2 KiB
application/rls-services+xml
init commit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | use std::collections::{HashMap, HashSet};
struct Regexp {
rules: HashMap<(usize, char), HashSet<usize>>,
end_states: HashSet<usize>
}
impl Regexp {
pub fn new(pattern: String) -> Self {
println!("> {pattern}");
let pattern_chars = Vec::from_iter(pattern.chars());
let mut star = false;
let mut plus = false;
let n = pattern.len();
let mut states = vec![HashSet::from([n])];
let mut end_states = HashSet::new();
let mut rules = HashMap::new();
for i in 0..n {
let j = n-i-1;
let c = pattern_chars[j];
let k = states.len()-1;
if c == '*' {
star = true;
continue;
}
if c == '+' {
plus = true;
continue;
}
if star {
states[k].insert(j);
println!("{j}: {:?}", states[k]);
Regexp::update_rule(&mut rules, j, &pattern_chars, &states[k]);
if states[k].contains(&n) {end_states.insert(j);}
star = false;
}
else if plus {
states[k].insert(j);
println!("{j}: {:?}", states[k]);
Regexp::update_rule(&mut rules, j, &pattern_chars, &states[k]);
if states[k].contains(&n) {end_states.insert(j);}
states.push(HashSet::from([j]));
plus = false;
}
else {
println!("{j}: {:?}", states[k]);
Regexp::update_rule(&mut rules, j, &pattern_chars, &states[k]);
if states[k].contains(&n) {end_states.insert(j);}
states.push(HashSet::from([j]));
}
if j == 0 {
let m = states.len()-1;
println!("99: {:?} (start)", states[m]);
Regexp::update_rule(&mut rules, 99, &pattern_chars, &states[m]);
if states[m].contains(&n) {end_states.insert(j);}
}
}
println!("{rules:?}");
return Regexp {rules, end_states};
}
pub fn eval(self, s: String) -> bool {
let mut multistate = HashSet::from([99]);
for c in s.chars() {
let mut new_multistate = HashSet::new();
for state in multistate {
if let Some(x) = self.rules.get(&(state, c)) {
new_multistate = new_multistate.union(&x).map(|&y| y).collect();
} else if let Some(x) = self.rules.get(&(state, '.')) {
new_multistate = new_multistate.union(&x).map(|&y| y).collect();
}
}
multistate = new_multistate;
}
return multistate.iter().any(|x| self.end_states.contains(x));
}
fn update_rule(rules: &mut HashMap<(usize, char), HashSet<usize>>, pos: usize, pattern: &Vec<char>, values: &HashSet<usize>) {
let n = pattern.len();
for &target in values.iter() {
println!("pos: {pos}, target: {target}");
if target == n {continue;}
let c = pattern[target];
let key = (pos, c);
if !rules.contains_key(&key) {rules.insert(key, HashSet::new());}
match rules.get_mut(&key) {
Some(set) => {set.insert(target);},
None => {rules.insert(key, HashSet::from([target]));}
};
}
}
fn find_previous_letter(s: &String, k: usize) -> Option<usize> {
return s[..k].rfind(char::is_alphanumeric);
}
fn find_next_letter(s: &String, k: usize) -> Option<usize> {
return s[k+1..].find(char::is_alphanumeric);
}
fn find_opening_parenthesis(s: &String, k: usize) -> Option<usize> {
let chars: Vec<char> = s.chars().collect();
let mut i = k;
let mut counter = 1;
while counter > 0 {
match chars[i] {
'(' => counter -= 1,
')' => counter += 1,
_ => {}
}
match i.checked_sub(1) {
Some(x) => i = x,
None => return None
}
}
return Some(i);
}
}
struct Solution {}
impl Solution {
pub fn is_match(s: String, p: String) -> bool {
let regexp = Regexp::new(p);
return regexp.eval(s);
}
}
fn main() {
// println!("{}\n", Solution::is_match(String::from("aa"), String::from("a")));
// println!("{}\n", Solution::is_match(String::from("aa"), String::from("a*")));
// println!("{}\n", Solution::is_match(String::from("ab"), String::from(".*")));
// println!("{}\n", Solution::is_match(String::from("aab"), String::from("a*ab")));
// println!("{}\n", Solution::is_match(String::from("aab"), String::from("a*b*")));
println!("{}\n", Solution::is_match(String::from("a"), String::from("a+")));
println!("{}\n", Solution::is_match(String::from("aa"), String::from("a+")));
println!("{}\n", Solution::is_match(String::from(""), String::from("a+")));
println!("{}\n", Solution::is_match(String::from("bb"), String::from("ba+b")));
println!("{}\n", Solution::is_match(String::from("baaaaab"), String::from("ba+b")));
}
|