我有我構建的NFA,並且正在運行此方法來評估計算機以查看錶達式是否有效。這適用於小的正則表達式,但是當我的正則表達式的大小以及因此我的NFA的大小變得太大時,此搜索會引發堆棧溢出。我相當肯定這是因爲我已經實現了一個BFS,我正在使用遞歸,並且可能沒有很好地處理我的基礎案例。如何避免使用此評估(BFS)的堆棧溢出
該方法採用表達式和節點(從NFA的開始節點開始)。首先檢查表達式的長度是否爲零,如果我處於接受節點(節點上的布爾值),則返回true。 如果表達式長度爲零,但當前節點不是接受節點,則返回false。
如果這些都沒有評估,那麼我得到當前節點可以使用「e」(ε)轉換到達的所有節點的列表,並對它們進行評估。
如果沒有「e」節點,那麼我從輸入表達式中移除第一個字符,縮小表達式的子串(移除表達式的前面),然後查找該節點的節點列表可以使用刪除的字符和減少的表達式。
如果沒有這些命中,然後我返回false
一個基本的正則表達式(A | B)*一個 和評價表述的一個例子是AAAA 它得到在每遍減少,AAAA - > AAA-> AA-> A->
private boolean evaluate(autoNode node, String expression)
{
if(expression.length()==0 && node.getAccept())
{
return true;
}
else if(expression.length()==0 && !node.getAccept())
{
return false;
}
String evalExp = expression.charAt(0)+""; //The first character in the expression
String redExp = expression.substring(1, expression.length());
//for each epsilon transition, evaluate it
if(node.getTransSet().contains("e"))
{
//if this node has an "e" transition then...
ArrayList<autoNode> EpsilonTransMap = node.getPathMap("e");
//The above ArrayList is a list of all the nodes that this node can reach
//using the "e"/epsilon transition
for(autoNode nodes : EpsilonTransMap)
{
if(evaluate(nodes, expression))
{
return true;
}
}
}
//for each transition on that key evaluate it
if(node.getTransSet().contains(evalExp))
{
//if this node has a transition from the front of the expression then...
ArrayList<autoNode> TransitionKeyMap = node.getPathMap(evalExp);
//The above ArrayList is a list of all the nodes that this node can reach
//on a transition equal to the "key" removed from the front of the expression String
for(autoNode nodes : TransitionKeyMap)
{
if(evaluate(nodes, redExp))
{
return true;
}
}
}
return false;
}
我知道,我可能通過使用BFS搜索,而不是DFS引起我自己的問題。我想知道是否有人可以幫助我解決這個問題,並避免因一次發生太多事情而導致堆棧溢出。因爲儘管(A | B)*一個可以評估就好了......
((AA)+ |(BB)+ |(CC)+)(BA)(CA)
創建相當大的NFA,在評估時會導致堆棧溢出: 「a」
任何不會導致我完全廢棄該方法的方法將非常有用。
也許,你可以嘗試轉換NFA到DFA,以減少回溯。 – sol