- 浏览: 939882 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
hw7777777:
非常感谢作者提供这么好的工具,在使用的过程中遇到一些问题?1、 ...
基于java nio的memcached客户端——xmemcached -
SINCE1978:
多久过去了时间能抹平一切
无路用的人 -
fangruanyjq:
[img][/img]引用
用osworkflow写一个请假例子(提供代码下载) -
thinkingmysky:
楼主,你确定,java memached client能处理并 ...
memcached java client性能测试的几点疑问和说明 -
hellostory:
aaa5131421 写道07年2月hibernate已经出来 ...
dozer与BeanUtils
今天有点空闲,想想用Ruby写个NFA试试。从正则表达式构造NFA采用经典的Thompson算法:正则表达式 -> 后缀表达式 -> 构造NFA。构造了NFA后,用之匹配字符串。一句话,写了个玩具的正则表达式引擎,支持concatenation、alternation以及 *、?、+量词,不支持反向引用和转义符。测试了下与Ruby自带的正则表达式引擎的性能对比,慢了3倍。构造NFA没什么问题,主要是匹配运行写的烂,有空再改改。
nfa.rb
module NFA class NFA def initialize(state) @state=state end def step(clist,c) return clist if clist.size==0; nlist=[] allNull = true matched = false clist.each do |t| if !t.nil? allNull = false if t.c!=-1 if t.c == c && t.end.type ==1 then matched = true nlist.push(t.end.out1) if !t.end.out1.end.nil? nlist.push(t.end.out2) if !t.end.out2.end.nil? elsif (t.c == c && t.end.type == 0) then matched = true; return ListUitls.new_list(t); elsif (t.c == -1 && !t.end.nil?) then nlist.push(t.end.out1); nlist.push(t.end.out2); end end end return step(nlist, c) if (allNull) return step(nlist, c) if (!matched) nlist end def test?(s) match(@state,s) end def match(state,s) clist =[] clist.push(state.out1); clist.push(state.out2); s.each_byte do |c| c =c&0xFF; clist = step(clist, c); return false if clist.size==0 end return is_match?(clist) end def is_match?(clist) clist.each do |t| return true if !t.nil? and t.c==-1 and t.end and t.end.is_matched? end false end end class Paren attr_accessor:n_alt,:n_atom end class State attr_accessor :out1,:out2,:type def initialize(out1,out2) @out1=out1 @out2=out2 @type=1 end def is_matched? return @type==0 end end class Transition attr_accessor :c,:end def initialize(c) @c=c end end class Frame attr_accessor :start,:outs def initialize(start,outs) @start=start @outs=outs end end class ListUitls def self.link(list,state) list.each{|t| t.end=state} end def self.append(list1,list2) list1+list2 end def self.new_list(out) result=[] result.push(out) result end end def self.compile(re) post = re2post(re) raise ArgumentError.new,"bad regexp!" if post.nil? state = post2nfa(post); raise RuntimeError.new,"construct nfa from postfix fail!" if state.nil? return NFA.new(state); end def self.post2nfa(postfix) stack=[] s=nil t=t1=t2=nil e1=e2=e=nil return nil if postfix.nil? postfix.each_byte do |p| case p.chr when '.': e2 = stack.pop() e1 = stack.pop() ListUitls.link(e1.outs, e2.start) stack.push(Frame.new(e1.start, e2.outs)) when '|': e2 = stack.pop() e1 = stack.pop() t1 = Transition.new(-1) t2 = Transition.new(-1) t1.end = e1.start t2.end = e2.start s = State.new(t1, t2) stack.push(Frame.new(s, ListUitls.append(e1.outs, e2.outs))) when '?': e = stack.pop() t1 = Transition.new(-1) t2 = Transition.new(-1) t1.end = e.start s = State.new(t1, t2) stack.push(Frame.new(s, ListUitls.append(e.outs, ListUitls.new_list(t2)))) when '*': e = stack.pop() t1 = Transition.new(-1) t2 = Transition.new(-1) t1.end = e.start s = State.new(t1, t2) ListUitls.link(e.outs, s) stack.push(Frame.new(s, ListUitls.new_list(s.out2))) when '+': e = stack.pop() t1 = Transition.new(-1) t2 = Transition.new(-1) t1.end = e.start s = State.new(t1, t2) ListUitls.link(e.outs, s) stack.push(Frame.new(e.start, ListUitls.new_list(t2))) else t = Transition.new(p) s = State.new(t, Transition.new(-1)) stack.push(Frame.new(s, ListUitls.new_list(s.out1))) end end e = stack.pop() return nil if stack.size()>0 end_state = State.new(nil, nil) end_state.type=0 e.outs.each do |tran| if tran.c!=-1 t1 = Transition.new(-1) t2 = Transition.new(-1) s=State.new(t1,t2) tran.end=s s.out1.end=end_state s.out2.end=end_state else tran.end=end_state end end start = e.start return start end def self.re2post(re) n_alt = n_atom = 0 result="" paren=[] re.each_byte do |c| case c.chr when '(' then if (n_atom > 1) then n_atom-=1 result<<"." end p =Paren.new p.n_alt = n_alt p.n_atom = n_atom paren.push(p) n_alt = n_atom = 0 when '|' then if (n_atom == 0) return nil end while (n_atom-=1) > 0 result<<"." end n_alt+=1 when ')' then if (paren.size() == 0) return nil end if (n_atom == 0) return nil end while (n_atom-=1)>0 result<<"." end while(n_alt>0) result<<"|" n_alt-=1 end p = paren.pop() n_alt = p.n_alt n_atom = p.n_atom n_atom+=1 when '*','+','?': if (n_atom == 0) return nil end result<<c else if (n_atom > 1) n_atom-=1 result<<"." end result<<c n_atom+=1 end end return nil if paren.size()>0 while ( (n_atom-=1)> 0) result<<"." end while(n_alt>0) n_alt-=1 result<<"|" end result end end
使用的话:
nfa = NFA::compile("a(bb)+a(cdf)*") assert nfa.test?("abba") assert nfa.test?("abbbba") assert !nfa.test?("a") assert !nfa.test?("aa") assert nfa.test?("abbacdf") assert nfa.test?("abbbbacdfcdf") assert !nfa.test?("bbbbacdfcdf") assert !nfa.test?("abbbacdfcdf") assert !nfa.test?("abbbbacdfdf") assert !nfa.test?("abbbbacdfdfg")
发表评论
-
使用Ruby amb解决说谎者谜题
2008-11-15 18:50 1602说谎者谜题是sicp4.3.2小节的一道题目,题目本身 ... -
swfheader 0.10 Released
2008-10-11 23:41 1520swfheader是一个处理swf文件的工具脚本,可用 ... -
Ruby 1.9概要(1)新的语法和语义
2008-10-01 13:37 1805一、新的语法和语义 1、新的Hash定义语法: 例如{a:2 ... -
Ruby 1.9概要(2)Kernel和Object
2008-10-01 13:48 1397二、Kernel 和 Object 1、引 ... -
Ruby 1.9概要(3)类和模块
2008-10-01 13:52 1404三、类和模块 1、Module#instance_method ... -
Ruby 1.9概要(4) Block和Proc
2008-10-02 13:54 13441、Proc加了新方法Proc#yield ,这只是Proc# ... -
Ruby 1.9概要(5) 异常
2008-10-03 13:26 13301、异常的相等性 ,如果两个异常的class、message和 ... -
Ruby Tip——读文件
2008-10-07 09:38 1834Ruby如何简洁地读整个文件,你可以这样做: f = Fil ... -
Ruby写Servlet的小例子
2008-07-23 12:05 2397Ruby也能写servlet?是的,没开玩笑,而且挺 ... -
JRuby中调用java带可变参数的方法
2008-06-14 22:41 1281今天同事遇到的问题,用JRuby调用一个java方 ... -
Ruby中实现stream
2008-05-08 22:36 1316流是通过延时求值实现的,Ruby中实现stream也 ... -
lua 5.0的实现(翻译)1,2,3部分
2008-04-07 17:28 3945三个多月前翻译的,今天又找出来看看,后面的整理再发。 原文: ... -
Ruby代码调整性能优化的几个Tip
2008-03-27 09:49 2183数据都是在我的 ... -
使用JProfiler监控JRuby脚本的运行
2008-03-24 15:32 1581jruby本质上也是启动一个jvm,然后去读Ru ... -
发布swf-util 0.01
2008-03-11 14:49 1812swf-util是一个使用Ruby读取swf头信息(高度、宽度 ... -
Ruby小技巧:处理方法调用中的nil
2008-02-19 13:41 3727读blog看到的一个小技巧,原文在这里。 我们 ... -
expectations——轻量级的单元测试框架
2008-02-16 10:05 1706项目主页:http://expectations.rubyfo ... -
JRuby中使用接口和抽象类
2008-02-15 14:36 1704要在JRuby中实现java接口,接口include进 ... -
google translator 0.2
2008-02-14 11:17 1905过去写的那个利用google在线翻译的小脚本工具一 直 ... -
JRuby的性能优化
2008-01-31 19:02 1738越来越觉的JRuby是个很有前途的项目,结合Ruby的 ...
相关推荐
NFA,全称“不确定的有限自动机”(Non-deterministic Finite Automaton),是自动机理论中的一个重要概念。本篇主要围绕NFA的概念、特点以及在Java中的实现进行深入探讨。 NFA是一种模型,用于识别和处理形式语言...
在这个实验中,我们将探讨NFA确定化的概念、方法以及如何通过编程实现这一过程。 NFA(非确定性有限状态自动机)具有以下特点: 1. 每个状态下都有多个可能的转移,对应于输入符号的不同组合。 2. NFA可以有 ε ...
用JAVA写的一个将正则表达式转换为NFA的代码,基于Thompson算法的思想,递归构建NFA。jar为源码文件。 输出非确定有限自动状态机的有向图。如正则表达式: c(a|b)NFA为:0-c->1-ep->2-a->3-ep->7 ,0-c->1-ep->4-b->5-...
用C语言实现NFA到DFA的转换过程 NFA (nondeterministic finite-state automata)是不确定性有限状态自动机的简写,NFA的定义为: 一个不确定性有限状态自动机由以下部分所组成: A. 一个有限的输入字符集I B. 一个...
Non-Deterministic Finite Automaton(NFA)是一种更一般的自动机,它的状态变迁函数是一个非确定的函数,即给定当前状态和输入符号,下一个状态可能有多个选择。NFA也可以用五元组M=(Q,∑,δ,q0,Z)来表示,但δ是从...
1. **NFA**:NFA是一种有限状态自动机,它允许在每个状态下根据当前输入符号有多个可能的转移。这种非确定性使得NFA能够更高效地处理某些正则表达式,但同时也带来了不确定性,即对于同一个输入序列,NFA可能有多种...
3. **Python实现细节**:描述如何用Python代码实现NFA和DFA的数据结构,以及如何定义转换函数。 4. **实验结果**:展示转换前后的状态图,以及对于不同输入字符串的识别情况。 5. **问题与解决方案**:可能遇到的...
这个过程会构建出一个状态转换表,表中的每个单元格代表一个DFA状态,对应着NFA的一组状态,单元格的每一列表示对某个输入字符的转移。 在Java中实现NFA到DFA的确定化,首先需要定义NFA和DFA的结构。NFA的状态通常...
NFA(非确定有限状态自动机)允许在每个状态下有多个可能的转移,即对于一个输入符号,NFA可以从当前状态转移到多个状态。DFA(确定有限状态自动机)则更严格,每个状态下对于每个输入符号只有一个确定的转移。DFA比...
本主题将深入探讨如何将NFA转换为DFA,并通过一个Java实现的程序来展示这一过程。 首先,NFA(Non-Deterministic Finite Automaton)是一种允许存在多种可能转移路径的自动机。每个状态下,对于同一个输入符号,它...
本人用c++写的一个将NFA转换成DFA的程序,希望大家指教。
本项目以"NFA转换为DFA(子集构造法)"为主题,旨在实现一个将非确定性自动机转化为确定性自动机的程序,算法基于编译原理教科书中的方法,作者陈意云。 首先,我们来理解NFA和DFA的基本概念。NFA是一种可能具有多...
并集通过创建一个新的起始状态,从该状态分别指向两个子NFA的起始状态,并将两个子NFA的终态合并为一个终态;闭包操作在原状态和自身之间添加一条ε转移。 4. **ε-归约**:在NFA构建完成后,可能需要进行ε-归约,...
1. **基础构造**:首先,为每个基本字符构造一个NFA状态,这个状态只接受该字符,并且从初始状态有边直接指向这个状态。 2. **组合运算符**:对于正则表达式的组合运算符如“+”(一次或多次)、“*”(零次或多次...
本资源“用Java做编译原理正规式转换成NFA.rar”主要关注的是编译原理中的一个重要概念——正规式到非确定性有限自动机(NFA)的转换。下面我们将深入探讨这个主题。 正规式是描述有限语言的数学表达式,常用于定义...
**非确定有限自动机(NFA)**是一种理论计算模型,它扩展了确定有限自动机(DFA)的概念,允许在某些情况下从一个状态出发到达多个状态。在NFA中,存在一种特殊的转移类型称为ε-转移,这种转移可以在不消耗任何输入符号...
在编译原理中,正规式(Regular Expression)与非确定性有限自动机(Non-Deterministic Finite Automaton,简称NFA)是两个重要的概念。正规式主要用于描述简单的字符串模式,而NFA则是一种数学模型,用于识别正规集...
编译原理的实验 NFA识别 java编写
#include #include class DFA; //声明DFA class NFA { char K[100]; //NFA的状态集合K ... // 创建一个NFA void PrintNFA();// 输出一个NFA friend void NFA_to_DFA(NFA &,DFA &);//实现NFA到DFA的转换 };
在C语言实现中,NFA通常用结构体表示状态,包括状态编号、转移函数(一个二维数组,每个元素指向下一个状态)和是否为接受状态的布尔标志。`N_DFA.c`可能是这样一个实现,包含了创建、添加转移和执行NFA匹配的函数。...