Skip to content

Commit 51019df

Browse files
committed
week3 kodutöö lahendus
1 parent db2137f commit 51019df

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

sols/week3/FiniteAutomaton.java

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package week3;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Paths;
5+
import java.util.*;
6+
7+
public class FiniteAutomaton extends AbstractAutomaton {
8+
private final Map<Integer, Map<Character, Set<Integer>>> transitions = new HashMap<>();
9+
private Integer startState = null;
10+
private final Set<Integer> acceptingStates = new HashSet<>();
11+
12+
@Override
13+
public void addState(int state) {
14+
transitions.put(state, new HashMap<>());
15+
}
16+
17+
@Override
18+
public void setStartState(int state) {
19+
startState = state;
20+
}
21+
22+
@Override
23+
public void addAcceptingState(int state) {
24+
acceptingStates.add(state);
25+
}
26+
27+
@Override
28+
public void addTransition(int fromState, Character label, int toState) {
29+
Map<Character, Set<Integer>> fromMap = transitions.get(fromState);
30+
Set<Integer> toSet = fromMap.computeIfAbsent(label, k -> new HashSet<>());
31+
toSet.add(toState);
32+
}
33+
34+
@Override
35+
public Set<Integer> getStates() {
36+
return transitions.keySet();
37+
}
38+
39+
@Override
40+
public Integer getStartState() {
41+
return startState;
42+
}
43+
44+
@Override
45+
public Set<Integer> getAcceptingStates() {
46+
return acceptingStates;
47+
}
48+
49+
@Override
50+
public Set<Character> getOutgoingLabels(int state) {
51+
return transitions.get(state).keySet();
52+
}
53+
54+
@Override
55+
public Set<Integer> getDestinations(int state, Character label) {
56+
return transitions.get(state).getOrDefault(label, Collections.emptySet());
57+
}
58+
59+
@Override
60+
public boolean accepts(String input) {
61+
Set<Integer> currentStates = epsilonClosure(Collections.singleton(startState));
62+
for (char c : input.toCharArray()) {
63+
if (currentStates.isEmpty()) return false;
64+
currentStates = move(currentStates, c);
65+
}
66+
return !Collections.disjoint(currentStates, acceptingStates);
67+
}
68+
69+
// Defineerime abifunktsioon step, millega saab nii sulund kui ka move defineerida.
70+
// See vaatab, kuhu võib etteantud tähega (muuhulgas epsiloniga) minna.
71+
private Set<Integer> step(Set<Integer> states, Character c) {
72+
Set<Integer> nextStates = new HashSet<>();
73+
for (Integer state : states) nextStates.addAll(getDestinations(state, c));
74+
return nextStates;
75+
}
76+
77+
public Set<Integer> epsilonClosure(Set<Integer> states) {
78+
Set<Integer> closure = new HashSet<>();
79+
while (closure.addAll(states)) states = step(states, null);
80+
return closure;
81+
//return Fixpoints.closure(x -> step(x, null), states);
82+
}
83+
84+
public Set<Integer> move(Set<Integer> states, Character c) {
85+
return epsilonClosure(step(states, c));
86+
}
87+
88+
/**
89+
* Seda meetodit ei hinnata ja seda ei pea muutma, aga läbikukkunud testide korral
90+
* antakse sulle automaadi kirjelduseks just selle meetodi tagastusväärtus.
91+
*/
92+
@Override
93+
public String toString() {
94+
return "trans: " + transitions + "\n" +
95+
"start: " + startState + ", end: " + acceptingStates;
96+
}
97+
98+
static void main() throws IOException {
99+
FiniteAutomaton fa = new FiniteAutomaton();
100+
101+
fa.addState(0);
102+
fa.addState(1);
103+
fa.addState(2);
104+
105+
fa.addTransition(0, 'b', 0);
106+
fa.addTransition(0, 'c', 2);
107+
fa.addTransition(2, 'a', 1);
108+
fa.addTransition(1, 'd', 0);
109+
fa.addTransition(0, null, 1);
110+
111+
fa.setStartState(0);
112+
fa.addAcceptingState(1);
113+
114+
System.out.println(fa.accepts("cadbbbca")); // true
115+
System.out.println(fa.accepts("abc")); // false
116+
System.out.println(fa.accepts("")); // true
117+
118+
// Pead ise veenduda, et toString töötab...
119+
System.out.println(fa);
120+
fa.renderPngFile(Paths.get("graphs", "auto.png"));
121+
}
122+
}

0 commit comments

Comments
 (0)