-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 81f08eb
Showing
39 changed files
with
3,566 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include "dfa.h" | ||
#define TRUE 1 | ||
#define FALSE 0 | ||
|
||
DFA *DFANew(int numStates) { | ||
DFA *dfa = (DFA*)malloc(sizeof(DFA)); | ||
dfa->numStates = numStates; | ||
dfa->currentState = 0; | ||
dfa->States = (DFAState*)malloc(numStates*sizeof(DFAState)); | ||
|
||
//setting all states to FALSE | ||
for(int i=0; i<numStates;i++) { | ||
dfa->States[i].isAccepting = FALSE; | ||
} | ||
//sets the transition to -1 which means no transiton | ||
for(int i1 =0;i1<numStates;i1++) { | ||
for(int j=0;j<128;j++){ | ||
dfa->States[i1].transitions[j] = -1; | ||
|
||
|
||
} | ||
} | ||
return dfa; | ||
} | ||
|
||
int DFAGetTransition(DFA *dfa, int stateNum, char symbol) { | ||
return dfa->States[stateNum].transitions[symbol]; | ||
} | ||
|
||
void DFASetTransition(DFA *dfa, int src, char str, int dst) { | ||
dfa->States[src].transitions[str] = dst; | ||
} | ||
|
||
void DFASetAllTransitions(DFA *dfa, int src, int dst) { | ||
|
||
for(int i=0;i<128;i++) { | ||
DFASetTransition(dfa,src,i,dst); | ||
} | ||
} | ||
|
||
int DFAGetCurrentState(DFA *dfa) { | ||
return dfa->currentState; | ||
} | ||
|
||
void DFASetCurrentState(DFA *dfa, int stateNum) { | ||
dfa->currentState = stateNum; | ||
} | ||
|
||
int DFAGetAccepting(DFA *dfa, int stateNum) { | ||
return dfa->States[stateNum].isAccepting; | ||
} | ||
|
||
void DFASetAccepting(DFA *dfa, int stateNum, BOOLEAN truthValue) { | ||
dfa->States[stateNum].isAccepting = truthValue; | ||
} | ||
|
||
|
||
void DFAPrint(DFA *dfa) { | ||
|
||
} | ||
|
||
int DFAExecute(DFA *dfa, char *input) { | ||
for(int i=0; input[i] != '\0'; i++) { | ||
int destination = dfa->States[dfa->currentState].transitions[input[i]]; | ||
DFASetCurrentState(dfa, destination); | ||
if(dfa->currentState == -1) { | ||
return FALSE; | ||
} | ||
|
||
} | ||
int finalState = dfa->currentState; | ||
DFASetCurrentState(dfa,0); | ||
return DFAGetAccepting(dfa, finalState); | ||
} | ||
|
||
//only string ab | ||
|
||
BOOLEAN funcOnlyAB() { | ||
DFA *onlyAB = DFANew(3); | ||
|
||
DFASetTransition(onlyAB, 0,'a',1); | ||
DFASetTransition(onlyAB,1,'b',2); | ||
DFASetAccepting(onlyAB, 2, TRUE); | ||
|
||
return onlyAB; | ||
|
||
|
||
} | ||
|
||
|
||
BOOLEAN funcStartAB() { | ||
DFA *startAB = DFANew(3); | ||
DFASetTransition(startAB,0, 'a', 1); | ||
DFASetTransition(startAB,1,'b',2); | ||
DFASetAllTransitions(startAB, 2,2); | ||
|
||
DFASetAccepting(startAB,2,TRUE); | ||
|
||
return startAB; | ||
} | ||
|
||
BOOLEAN funcEvenOnes() { | ||
|
||
DFA *evenOnes = DFANew(2); | ||
|
||
|
||
DFASetTransition(evenOnes,0,'1',1); | ||
DFASetTransition(evenOnes,1,'1',0); | ||
DFASetTransition(evenOnes, 0,'0',0); | ||
DFASetTransition(evenOnes, 1,'0',1); | ||
|
||
DFASetAccepting(evenOnes,0,TRUE); | ||
|
||
|
||
return evenOnes; | ||
|
||
|
||
} | ||
|
||
|
||
|
||
|
||
BOOLEAN funcEvenBoth() { | ||
|
||
DFA *evenBoth = DFANew(4); | ||
|
||
DFASetTransition(evenBoth,0,'0',1); | ||
DFASetTransition(evenBoth,1,'0',0); | ||
DFASetTransition(evenBoth,1,'1',2); | ||
DFASetTransition(evenBoth,2,'1',1); | ||
DFASetTransition(evenBoth,2,'0',3); | ||
DFASetTransition(evenBoth,3,'0',2); | ||
DFASetTransition(evenBoth,3,'1',0); | ||
DFASetTransition(evenBoth,0,'1',3); | ||
DFASetAccepting(evenBoth,0,TRUE); | ||
|
||
return evenBoth; | ||
|
||
|
||
} | ||
|
||
//for indentifying if string starts with $ sign | ||
//Useful for checking if it's an amount of money. | ||
//Would return false if any character after dollar sign is not a number | ||
//Easy to implement | ||
|
||
BOOLEAN funcStartDolSign() { | ||
DFA *startDolSign = DFANew(2); | ||
|
||
|
||
|
||
// DFASetAllTransitions(startDolSign,0,0); | ||
// DFASetAllTransitions(startDolSign,1,1); | ||
DFASetTransition(startDolSign,0,'$',1); | ||
//iterating over all ascii | ||
//values for number characters | ||
for(int i =48;i<=57;i++) { | ||
DFASetTransition(startDolSign,1,i,1); | ||
|
||
} | ||
|
||
DFASetAccepting(startDolSign,1,TRUE); | ||
|
||
return startDolSign; | ||
|
||
} | ||
|
||
|
||
|
||
|
||
int main() { | ||
|
||
|
||
|
||
char *inputString1 = "ab"; | ||
char *inputString2 = "abg"; | ||
char *inputString3 = "babcdef"; | ||
char *inputString4 = "111001"; | ||
char *inputString5 = "1101101"; | ||
char *inputString6 = "$150"; | ||
char *inputString7 = "15a0"; | ||
char *inputString8 = "man"; | ||
|
||
|
||
|
||
printf("funcOnlyAB(%s) = %d\n", inputString1, DFAExecute(funcOnlyAB(),inputString1)); | ||
printf("funcOnlyAB(%s) = %d\n", inputString2, DFAExecute(funcOnlyAB(), inputString2)); | ||
printf("funcStartAB(%s) = %d\n", inputString2, DFAExecute(funcStartAB(),inputString2)); | ||
printf("funcStartAB(%s) = %d\n", inputString3, DFAExecute(funcStartAB(),inputString3)); | ||
printf("funcEvenOnes(%s) = %d\n", inputString4, DFAExecute(funcEvenOnes(),inputString4)); | ||
printf("funcEvenOnes(%s) = %d\n", inputString5, DFAExecute(funcEvenOnes(),inputString5)); | ||
printf("funcEvenBoth(%s) = %d\n", inputString4, DFAExecute(funcEvenBoth(),inputString4)); | ||
printf("funcEvenBoth(%s) = %d\n", inputString5, DFAExecute(funcEvenBoth(),inputString5)); | ||
printf("funcStartDolSign(%s) = %d\n", inputString6, DFAExecute(funcStartDolSign(),inputString6)); | ||
printf("funcStartDolSign(%s) = %d\n", inputString7, DFAExecute(funcStartDolSign(),inputString7)); | ||
// printf("%d", DFAExecute(funcEndMAN(),inputString8)); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include "IntSet.h" | ||
|
||
/** | ||
* Toplevel structure for an IntSet. | ||
* This implementation simply uses a linked list. | ||
*/ | ||
struct IntSet { | ||
struct IntSetNode *first; | ||
struct IntSetNode *last; | ||
}; | ||
|
||
struct IntSetIterator { | ||
struct IntSetNode *node; | ||
}; | ||
|
||
/** | ||
* Structure for each element in an IntSet, stored as a linked list. | ||
*/ | ||
typedef struct IntSetNode { | ||
int value; | ||
struct IntSetNode *next; | ||
} IntSetNode; | ||
|
||
/** | ||
* Allocate, initialize and return a new (empty) IntSet. | ||
*/ | ||
IntSet * | ||
IntSet_new() { | ||
IntSet *set = (IntSet*)malloc(sizeof(IntSet)); | ||
set->first = set->last = NULL; | ||
return set; | ||
} | ||
|
||
/** | ||
* Free the memory used for the given IntSet and all its elements. | ||
*/ | ||
void | ||
IntSet_free(IntSet *set) { | ||
// Free the elements | ||
IntSetNode *elt = set->first; | ||
while (elt != NULL) { | ||
IntSetNode *next = elt->next; | ||
free(elt); | ||
elt = next; | ||
} | ||
// Free the set (list) | ||
free(set); | ||
} | ||
|
||
/** | ||
* Allocate and initialize a new IntSetNode storing the given int value. | ||
*/ | ||
static IntSetNode * | ||
IntSetNode_new(int value) { | ||
IntSetNode *node = (IntSetNode*)malloc(sizeof(IntSetNode)); | ||
if (node == NULL) { | ||
abort(); | ||
} | ||
node->value = value; | ||
node->next = NULL; | ||
return node; | ||
} | ||
|
||
/** | ||
* Return true if the given IntSet is empty. | ||
*/ | ||
bool | ||
IntSet_is_empty(const IntSet *set) { | ||
return set->first == NULL; | ||
} | ||
|
||
/** | ||
* Add given int to the given IntSet (if it's not already there). | ||
*/ | ||
void | ||
IntSet_add(IntSet *set, int value) { | ||
if (!IntSet_contains(set, value)) { | ||
// Add at front | ||
IntSetNode *node = IntSetNode_new(value); | ||
node->next = set->first; | ||
set->first = node; | ||
} | ||
} | ||
|
||
/** | ||
* Return true if the given IntSet contains the given int value. | ||
*/ | ||
bool | ||
IntSet_contains(const IntSet *set, int value) { | ||
for (IntSetNode *node=set->first; node != NULL; node=node->next) { | ||
if (node->value == value) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Add the contents of IntSet set2 to IntSet set1 (adding those elements | ||
* that aren't already in set1). This will modify set1 unless set2 is empty | ||
* (or all its elements are already in set1). | ||
*/ | ||
void | ||
IntSet_union(IntSet *set1, const IntSet *set2) { | ||
for (IntSetNode *node=set2->first; node != NULL; node=node->next) { | ||
IntSet_add(set1, node->value); | ||
} | ||
} | ||
|
||
/** | ||
* Return true if the first IntSet contains every member of the second | ||
* IntSet. | ||
*/ | ||
bool | ||
IntSet_contains_all(IntSet *set1, IntSet *set2) { | ||
for (IntSetNode *node2=set2->first; node2 != NULL; node2=node2->next) { | ||
if (!IntSet_contains(set1, node2->value)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Return true if the two given IntSets contain exactly the same members, | ||
* otherwise false. | ||
*/ | ||
bool | ||
IntSet_equals(IntSet *set1, IntSet *set2) { | ||
return IntSet_contains_all(set1, set2) && IntSet_contains_all(set2, set1); | ||
} | ||
|
||
/** | ||
* Call the given function on each element of given IntSet, passing the | ||
* int value to the function. | ||
*/ | ||
void | ||
IntSet_iterate(const IntSet *set, void (*func)(int)) { | ||
for (IntSetNode *node=set->first; node != NULL; node=node->next) { | ||
func(node->value); | ||
} | ||
} | ||
|
||
/** | ||
* Return an IntSetIterator for the given IntSet. | ||
* Don't forget to free() this when you're done iterating. | ||
*/ | ||
|
||
IntSetIterator * | ||
IntSet_iterator(const IntSet *set) { | ||
IntSetIterator *iterator = (IntSetIterator*)malloc(sizeof(IntSetIterator)); | ||
iterator->node = set->first; | ||
return iterator; | ||
} | ||
|
||
/** | ||
* Return the next int from the given IntSetIterator and increment it | ||
* to point to the next element. | ||
* This will cause a crash if there is no such element. | ||
* You could make a safe version with a pass-by-reference (int*) parameter | ||
* for the int and boolean return value that indicates whether the operation | ||
* succeeded or not. Ah, the goold old days... | ||
*/ | ||
bool | ||
IntSetIterator_has_next(const IntSetIterator *iterator) { | ||
return iterator != NULL && iterator->node != NULL; | ||
} | ||
|
||
int | ||
IntSetIterator_next(IntSetIterator *iterator) { | ||
if (iterator == NULL || iterator->node == NULL) { | ||
abort(); | ||
} else { | ||
int value = iterator->node->value; | ||
iterator->node = iterator->node->next; | ||
return value; | ||
} | ||
} | ||
|
||
/** | ||
* Print the given IntSet to stdout. | ||
*/ | ||
void | ||
IntSet_print(IntSet *set) { | ||
for (IntSetNode *node=set->first; node != NULL; node=node->next) { | ||
printf("%d", node->value); | ||
if (node->next != NULL) { | ||
printf(" "); | ||
} | ||
} | ||
printf("\n"); | ||
} |
Oops, something went wrong.