Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
cxx = gcc -std=c99

cflags = -O3 -g -Wall --pedantic -fopenmp -funroll-loops -DNDEBUG


rootPath = ./
libPath = ${rootPath}impl/
headers = ${rootPath}inc/
binPath = ${rootPath}bin/

libSources = ${libPath}*.c


all: dictionary.a
${cxx} ${cflags} -I inc -I ${headers} -o ${binPath}test_dictionary ${rootPath}test_dictionary.c ${binPath}dictionary.a
chmod ugo+xwr ${binPath}test_dictionary

dictionary.a :
mkdir -v -p ${binPath}
${cxx} ${cflags} -I ${headers} -c ${libSources}
ar rc dictionary.a *.o
ranlib dictionary.a
rm *.o
mv dictionary.a ${binPath}

.PHONY: all dictionary.a
11 changes: 0 additions & 11 deletions Rosalind 5.py

This file was deleted.

224 changes: 161 additions & 63 deletions Dictionary.c → impl/Dictionary.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,61 @@
#include<assert.h>
#include"Dictionary.h"

//const int TABLESIZE = 180;
// for you need a constant here and based on what I saw 'const' doesnt mean that it is a C 'constant'
// https://stackoverflow.com/questions/2308194/shall-i-prefer-constants-over-defines/2308364#2308364
// I set the tablesize to 3 so we can test chaining
#define TABLESIZE 3

// TODO you should define the structs in the header file so they are easy to use later
// NodeObj
const int tablesize = 180;
int items = 0;
struct NodeObj{
char* key;
char* value;
struct NodeObj* next;
struct NodeObj* prev;
} NodeObj;

// Node

// newNode()
// constructor of the Node type
struct NodeObj* newNode(char* k, char* v) {
struct NodeObj* N = calloc(1,sizeof(NodeObj));
N->key = calloc(strlen(k)+1, sizeof(char));
N->value = calloc(strlen(v)+1, sizeof(char));
struct NodeObj* N = (struct NodeObj*) calloc(1,sizeof(NodeObj));
// N->key = calloc(strlen(k)+1, sizeof(char));
// N->value = calloc(strlen(v)+1, sizeof(char));
// this memory was already allocated with the calloc call
N->key = k;
N->value = v;
N->next = NULL;
return(N);
}

// freeNode()
// destructor for the Node type
void freeNode(struct NodeObj** pN){
if( pN!=NULL && *pN!=NULL ){
free((*pN)->key);
free((*pN)->value);
free(*pN);
*pN = NULL;
int freeNode(struct NodeObj* pN){
int n_nodes = 0;
if(pN != NULL){
struct NodeObj* next_node = pN->next;
free(pN);
n_nodes++;
while (next_node != NULL){
struct NodeObj* next_next = next_node->next;
free(next_node);
n_nodes++;
next_node = next_next;
}
}
return n_nodes;
}



// DictionaryObj
struct DictionaryObj{
struct NodeObj* root;
struct NodeObj* table[tablesize];
struct NodeObj* table[TABLESIZE];
int numPairs;
} DictionaryObj;
typedef struct DictionaryObj* Dictionary;


// public functions -----------------------------------------------------------
Expand All @@ -63,15 +77,45 @@ Dictionary newDictionary(void){

// freeDictionary()
// destructor for the Dictionary type
void freeDictionary(Dictionary* pD){
if(pD!=NULL && *pD!=NULL ){
if( !isEmpty(*pD) ) makeEmpty(*pD);
//free(*pD->table);
free(*pD);
*pD = NULL;
//void freeDictionary(Dictionary pD){
// if(pD!=NULL){
// if( !isEmpty(pD) ) makeEmpty(*pD);
// //free(*pD->table);
// free(*pD);
// *pD = NULL;
// }
//}

void freeDictionary(Dictionary pD){
if(pD!=NULL){
if( !isEmpty(pD) ){
makeEmpty(pD);
}
free(pD);
}
}

// makeEmpty()
// re-sets D to the empty state.
// pre: none
void makeEmpty(Dictionary D){
//setting top/bot to NULL and items to zero empties the Dictionary
int counter = 0;
int num_elements = 0;
while(num_elements < D->numPairs){
if (D->table[counter] != NULL){

int nodes_deconstructed = freeNode(D->table[counter]);
D->table[counter] = NULL;
num_elements += nodes_deconstructed;
}
counter++;
}
D->numPairs = 0;

}


// rotate_left()
// rotate the bits in an unsigned int
unsigned int rotate_left(unsigned int value, int shift) {
Expand All @@ -98,8 +142,9 @@ unsigned int pre_hash(char* input) { // input points to first char in string
// hash()
// turns a string into an int in the range 0 to tableSize-1
int hash(char* key){
int a = pre_hash(key);
a = a%(tablesize);
// This also needs to be unsigned because you are converting an unsigned int to int so it could become negative
unsigned int a = pre_hash(key);
a = a%(TABLESIZE);
return a;
}
// isEmpty()
Expand Down Expand Up @@ -128,15 +173,26 @@ struct NodeObj* find(Dictionary D, char* k){
int hashkey = hash(k);
if(D->table[hashkey] == NULL)
return NULL;
while(D->table[hashkey]!= NULL)
{
if(D->table[hashkey]->key == k)
return D->table[hashkey];
if(D->table[hashkey]->next == NULL)
break;
D->table[hashkey] = D->table[hashkey]->next;
}
return NULL;
if(D->table[hashkey]->key == k)
return D->table[hashkey];
if(D->table[hashkey]->next == NULL)
return NULL;
else {
struct NodeObj* node = D->table[hashkey]->next;

while(node != NULL)
{
if(node->key == k)
return node;
if(node->next == NULL)
return NULL;
else{
node = node->next;
}
}
return NULL;

}
}

// size()
Expand All @@ -155,18 +211,19 @@ int size(Dictionary D){
// such value v exists.
// pre: none
char* lookup(Dictionary D, char* k){
if(items == 0)
return NULL;
//if the Dictionary is NULL throw an error
if( D==NULL ){
if( D == NULL ){
fprintf(stderr, "Dictionary Error: calling lookup() on NULL Dictionary reference\n");
exit(EXIT_FAILURE);
}
if(D->numPairs == 0)
return NULL;

//initialize N the key to be found so the corresponding value can be found
struct NodeObj* N = find(D, k);
if (N == NULL){
return NULL;
}else{
} else{
return N->value;
}
}
Expand All @@ -182,20 +239,34 @@ void insert(Dictionary D, char* k, char* v){
fprintf(stderr, "Dictionary Error: cannot call insert on a NULL Dictionary");
exit(EXIT_FAILURE);
}
if (lookup(D, k) != NULL){
fprintf(stderr, "Dictionary Error: cannot insert duplicate keys\n");
exit(EXIT_FAILURE);
}
//intialize a new Node object if current node is empty
struct NodeObj* N = newNode(k, v);
D->numPairs++;
items = D->numPairs;
int hashIndex = hash(k);
while(D->table[hashIndex] != NULL)
{
D->table[hashIndex] = D->table[hashIndex]->next;

struct NodeObj* node = D->table[hashIndex];
if (node != NULL){
for (int i =0; i< D->numPairs; i++)
{
if(node->key == k){
// this should never happen
fprintf(stderr, "Dictionary Error: cannot insert duplicate keys\n");
exit(EXIT_FAILURE);
}
if(node->next == NULL){
node->next=N;
N->prev=node;
break;
}
else{
struct NodeObj* node2 = node->next;
node = node2;
}
}

} else {
D->table[hashIndex] = N;
}
D->table[hashIndex] = N;
}

// delete()
Expand All @@ -209,39 +280,66 @@ void delete(Dictionary D, char* k){
}
//if the current key in the dictionary does not match the key we are looking
//for, move on.
free(&D->table[hash(k)]);
// Find node, delete after reconnecting nodes
// recreate connection between linked list
// this is pretty hacky and there should be functions for all these linked list operations
struct NodeObj* node = find(D, k);
if (node->next != NULL || node->prev != NULL){
struct NodeObj* prev_node = node->prev;
struct NodeObj* next_node = node->next;

if (prev_node != NULL){
if (next_node != NULL) {
prev_node->next = node->next;
node->next->prev = prev_node;
} else {
prev_node->next = NULL;
}
} else {
D->table[hash(k)] = next_node;
}
} else {
D->table[hash(k)] = NULL;
}
free(node);
D->numPairs--;
items--;
}

// makeEmpty()
// re-sets D to the empty state.
// pre: none
void makeEmpty(Dictionary D){
//setting top/bot to NULL and items to zero empties the Dictionary
int counter = 0;
while(&(D->table[counter]) != NULL && counter < D->numPairs){
struct NodeObj* N;
*N = *D->table[counter];
D->table[counter]=N->next;
freeNode(&N);
N = NULL;
counter++;
}
D->numPairs = 0;

}
//void makeEmpty(Dictionary D){
// //setting top/bot to NULL and items to zero empties the Dictionary
// int counter = 0;
// while(&(D->table[counter]) != NULL && counter < D->numPairs){
// struct NodeObj* N;
// *N = *D->table[counter];
// freeNode(N);
// N = NULL;
// counter++;
// }
// D->numPairs = 0;
//
//}

void printDictionary(FILE* out, Dictionary D){
if(D==NULL){
fprintf(stderr, "Dictionary Error: printDictionary() called on NULL Dictionary reference\n");
exit(EXIT_FAILURE);
}
for(int i =0; i< tablesize; i++){
while(D->table[i] != NULL){
for(int i =0; i< TABLESIZE; i++){
// BORA: you were reassigning each value during that while loop so basically you assign values to NULL
if (D->table[i] != NULL){
fprintf(out, "%s %s \n" , D->table[i]->key, D->table[i]->value);
D->table[i] = D->table[i]->next;
struct NodeObj* node = D->table[i]->next;
// check the chained dictionary
while (node != NULL) {
fprintf(out, "%s %s \n" , node->key, node->value);
struct NodeObj* node2 = node->next;
node = node2;
}
}
}
}


Loading