Skip to content

Commit 9fd203d

Browse files
Merge pull request wangzheng0822#271 from WayneCui/master
FEAT: add ac_automata_unicode and DSF by JS
2 parents f3f7d60 + 651c3f7 commit 9fd203d

File tree

2 files changed

+200
-0
lines changed

2 files changed

+200
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
2+
class ACNode {
3+
constructor(data){
4+
this.data = data;
5+
this.children = new Map();
6+
this.isEndingChar = false;
7+
this.length = 0;
8+
this.fail = null;
9+
}
10+
}
11+
12+
class ACTree {
13+
14+
constructor(data){
15+
this.root = new ACNode('/')
16+
}
17+
18+
insert (text) {
19+
let node = this.root;
20+
for (let char of text) {
21+
if(!node.children.get(char)) {
22+
node.children.set(char, new ACNode(char));
23+
}
24+
node = node.children.get(char);
25+
}
26+
27+
node.isEndingChar = true;
28+
node.length = text.length;
29+
}
30+
31+
buildFailurePointer() {
32+
let root = this.root;
33+
let queue = [];
34+
queue.push(root);
35+
36+
while (queue.length > 0) {
37+
let p = queue.shift();
38+
39+
for(var pc of p.children.values()){
40+
if (!pc) {
41+
continue;
42+
}
43+
44+
if(p == root) {
45+
pc.fail = root;
46+
} else {
47+
let q = p.fail;
48+
while (q) {
49+
let qc = q.children.get(pc.data);
50+
if(qc) {
51+
pc.fail = qc;
52+
break;
53+
}
54+
q = q.fail;
55+
}
56+
if(!q) {
57+
pc.fail = root;
58+
}
59+
}
60+
queue.push(pc);
61+
}
62+
}
63+
}
64+
65+
match (text) {
66+
let root = this.root;
67+
let n = text.length;
68+
let p = root;
69+
70+
for(let i = 0; i < n; i++) {
71+
let char = text[i];
72+
while(!p.children.get(char) && p != root){
73+
p = p.fail;
74+
}
75+
76+
p = p.children.get(char);
77+
if(!p) {
78+
p = root;
79+
}
80+
81+
let tmp = p;
82+
while ( tmp != root) {
83+
if (tmp.isEndingChar == true) {
84+
console.log(`Start from ${i - p.length + 1}, length: ${p.length}`);
85+
}
86+
tmp = tmp.fail;
87+
}
88+
}
89+
}
90+
}
91+
92+
function match( text, patterns) {
93+
let automata = new ACTree();
94+
for (let pattern of patterns) {
95+
automata.insert(pattern);
96+
}
97+
98+
automata.buildFailurePointer();
99+
automata.match(text);
100+
}
101+
102+
let patterns = ["at", "art", "oars", "soar"];
103+
let text = "soarsoars";
104+
match(text, patterns);
105+
106+
let patterns2 = ["Fxtec Pro1", "谷歌Pixel"];
107+
let text2 = "一家总部位于伦敦的公司Fxtex在MWC上就推出了一款名为Fxtec Pro1的手机,该机最大的亮点就是采用了侧滑式全键盘设计。DxOMark年度总榜发布 华为P20 Pro/谷歌Pixel 3争冠";
108+
match(text2, patterns2);
109+
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
2+
function Graph() {
3+
var graph = {
4+
adj: new Map(),
5+
addEdge: function (from, to){
6+
if(!this.adj.get(from)) {
7+
this.adj.set(from, [ to ]);
8+
} else {
9+
this.adj.get(from).push(to);
10+
}
11+
},
12+
sortingByDsf: function(){
13+
var inverseAdj = new Map();
14+
var keys = this.adj.keys();
15+
for(let key of keys) {
16+
let blk = this.adj.get(key);
17+
if(blk) {
18+
for(let v of blk) {
19+
if(!inverseAdj.get(v)) {
20+
inverseAdj.set(v, [key]);
21+
} else {
22+
inverseAdj.get(v).push(key);
23+
}
24+
}
25+
}
26+
}
27+
28+
let inKeys = inverseAdj.keys();
29+
let vertexes = new Set([...keys, ...inKeys]);
30+
let visited = [];
31+
for(let vertex of vertexes) {
32+
if(!visited.includes(vertex)) {
33+
visited.push(vertex);
34+
this.dsf(vertex, inverseAdj, visited);
35+
}
36+
}
37+
},
38+
dsf: function(vertex, inverseAdj, visited) {
39+
if(!inverseAdj.get(vertex)) {
40+
inverseAdj.set(vertex, []);
41+
}
42+
43+
for(let v of inverseAdj.get(vertex)) {
44+
if(visited.includes(v)) {
45+
continue;
46+
}
47+
48+
visited.push(v);
49+
50+
this.dsf(v, inverseAdj, visited);
51+
}
52+
53+
console.log("->" + vertex);
54+
}
55+
}
56+
57+
return graph;
58+
}
59+
60+
var dag = new Graph();
61+
dag.addEdge(2, 1);
62+
dag.addEdge(3, 2);
63+
dag.addEdge(2, 4);
64+
dag.addEdge(4, 1);
65+
dag.sortingByDsf();
66+
67+
68+
var dag2 = new Graph();
69+
dag2.addEdge("main", "parse_options");
70+
dag2.addEdge("main", "tail_file");
71+
dag2.addEdge("main", "tail_forever");
72+
dag2.addEdge("tail_file", "pretty_name");
73+
dag2.addEdge("tail_file", "write_header");
74+
dag2.addEdge("tail_file", "tail");
75+
dag2.addEdge("tail_forever", "recheck");
76+
dag2.addEdge("tail_forever", "pretty_name");
77+
dag2.addEdge("tail_forever", "write_header");
78+
dag2.addEdge("tail_forever", "dump_remainder");
79+
dag2.addEdge("tail", "tail_lines");
80+
dag2.addEdge("tail", "tail_bytes");
81+
dag2.addEdge("tail_lines", "start_lines");
82+
dag2.addEdge("tail_lines", "dump_remainder");
83+
dag2.addEdge("tail_lines", "file_lines");
84+
dag2.addEdge("tail_lines", "pipe_lines");
85+
dag2.addEdge("tail_bytes", "xlseek");
86+
dag2.addEdge("tail_bytes", "start_bytes");
87+
dag2.addEdge("tail_bytes", "dump_remainder");
88+
dag2.addEdge("tail_bytes", "pipe_bytes");
89+
dag2.addEdge("file_lines", "dump_remainder");
90+
dag2.addEdge("recheck", "pretty_name");
91+
dag2.sortingByDsf();

0 commit comments

Comments
 (0)