电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

生成随机数与字母


发布日期:2021/2/23
 
题目如下

Write a parser for a simplified regular expression

On an alphabet set [az] a simplified regular expression is much simpler than the normal regular expression

It has only two meta characters: and *

exact one arbitrary character match

* zero or more arbitrary character match

举个例子表达式 ab*d 能匹配 abcd abccd abad 不能匹配abc (空字符串) abd

解法

解析给定的表达式

生成对应的 NFA(Nondeterministic Finite Automation)

NFA转化为DFA(Deterministic Finite Automation)

利用DFA判断输入字符串

相关代码

FiniteAutomatajava 和Statejava随手写写请选择性参考

FiniteAutomatajava

package parser;

import javautilHashMap;

import javautilHashSet;

import javautilIterator;

import javautilLinkedList;

import javautilMap;

import javautilMapEntry;

import javautilQueue;

import javautilSet;

public class FiniteAutomata {

private State start;

private final static char[] inputs;

static {

inputs = new char[];

for (char i = ; i < ; i++) {

inputs[i] = (char) (a + i)

}

}

private final char episilon = ;

private char stateId;

public void compile(String pattern) {

thisstateId = A;

State NFA = toNFA(pattern)

thisstart = convertToDFA(NFA)

}

private State convertToDFA(State NFA) {

Map<Set<State> State> cache = new HashMap<Set<State> State>()

Queue<Set<State》 queue = new LinkedList<Set<State》()

// start state of DFA

Set<State> start = episilon(NFA)

State starter = nextState()

cacheput(start starter)

queueoffer(start)

while (!queueisEmpty()) {

Set<State> currentEpisilon = queuepoll()

State current = cacheget(currentEpisilon)

// create new State

for (char input : inputs) {

Set<State> nextEpisilon = move(currentEpisilon input)

if (nextEpisilonisEmpty()) {

continue;

}

State next;

if (!ntainsKey(nextEpisilon)) {

next = nextState()

cacheput(nextEpisilon next)

queueoffer(nextEpisilon)

} else {

next = cacheget(nextEpisilon)

}

boolean isAccept = containsAcceptState(nextEpisilon)

nextsetAccept(isAccept)

currentsetTransition(input next)

}

}

return starter;

}

private Set<State> move(Set<State> currentEpisilon char input) {

Set<State> result = new HashSet<State>()

for (State s : currentEpisilon) {

State next = stransit(input)

if (next != null) {

resultadd(next)

}

}

return episilon(result)

}

private boolean containsAcceptState(Set<State> nextEpisilon) {

for (State state : nextEpisilon) {

if (stateisAccept()) {

return true;

}

}

return false;

}

private Set<State> episilon(State s) {

Set<State> cache = new HashSet<State>()

cacheadd(s)

return episilon(s cache)

}

private Set<State> episilon(Set<State> states) {

Set<State> cache = new HashSet<State>()

for (State s : states) {

cacheadd(s)

cacheaddAll(episilon(s cache))

}

return cache;

}

private Set<State> episilon(State s Set<State> cache) {

State next = stransit(episilon)

if (next != null && !ntains(next)) {

cacheadd(next)

cacheaddAll(episilon(s cache))

}

return cache;

}

private State toNFA(String pattern) {

char[] expr = patterntoCharArray()

State currentState = nextState()

State starter = currentState;

for (char c : expr) {

if (c == ) {

State nextState = nextState()

// add each transition for all inputs

for (char i : inputs) {

currentStatesetTransition(i nextState)

}

currentState = nextState;

} else if (c == *) {

State nextState = nextState()

// add each transition for all inputs

for (char i : inputs) {

currentStatesetTransition(i nextState)

}

currentStatesetTransition(episilon nextState)

nextStatesetTransition(episilon currentState)

currentState = nextState;

} else if (c >= a && c <= z) {

State nextState = nextState()

currentStatesetTransition(c nextState)

currentState = nextState;

} else {

throw new RuntimeException(Unrecognized expression

}

}

currentStatesetAccept(true)

return starter;

}

private State nextState() {

return new State(stateId++)

}

public void constructDFA(Map<State Map<Character State》 mapping) {

Iterator<MapEntry<State Map<Character State>>> it = mapping

entrySet()iterator()

while (ithasNext()) {

Entry<State Map<Character State》 entry = itnext()

State state = entrygetKey()

Map<Character State> transition = entrygetValue()

statesetTransition(transition)

}

}

public boolean match(String c) {

char[] candidate = ctoCharArray()

for (char d : candidate) {

start = starttransit(d)

if (start == null) {

return false;

}

}

return startisAccept()

}

public static String[] patterns = { abc * *abc *abc a*bc

a*bc a* a* a* a* *abc* ***** *

bc* b*c*a * abc *a a a*c a*b

};

public static String[] candidates = { abc abc abc aaabbbabc

aaabbbabc abc abc a aa abcdef abc abc

abc abc abc abca abcd abcd abc abc

abc abc };

public static void main(String[] args) {

FiniteAutomata fa = new FiniteAutomata()

for (int i = ; i < patternslength; i++) {

pile(patterns[i])

Systemoutprintln(famatch(candidates[i]))

}

}

}

Statejava

package parser;

import javautilHashMap; import javautilMap;

public class State {

private boolean accept = false;

private char id;

private Map<Character State> mapping = new HashMap<Character State>()

public State(char c) {

thisid = c;

}

public State(char c boolean isAccept) {

thisid = c;

thisaccept = isAccept;

}

public State transit(char input) {

return mappingget(input)

}

public void setTransition(char input State next) {

thismappingput(input next)

}

public void setTransition(Map<Character State> mapping) {

thismapping = mapping;

}

public boolean isAccept() {

return thisaccept;

}

public void setAccept(boolean b) {

thisaccept = b;

}

@Override

public int hashCode() {

final int prime = ;

int result = ;

result = prime * result + id;

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != objgetClass())

return false;

State other = (State) obj;

if (id != otherid)

return false;

return true;

}

@Override

public String toString() {

return State [id= + id + ];

}

}

上一篇:内框架Iframe的使用

下一篇:Biztalk 开发之 架构和实例的验证