Initial commit of code for dopelib, and ch 1, 2, and 12

This commit is contained in:
2024-10-29 16:04:54 -04:00
parent 11601352d3
commit afbf4c2f7e
25 changed files with 745 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
#pragma once
#include <stdlib.h>
bool IsUnique(const char* s, int len);
bool CheckPermutation(const char* s1, const char* s2, size_t s1_len, size_t s2_len);

View File

@@ -0,0 +1,35 @@
#include <iostream>
#include <string>
#include "chapter1.hpp"
/* Prompt
Check Permutation: Given two strings, write a method to decide if
one is a permutation of the other.
*/
bool CheckPermutation(const char* s1, const char* s2,
size_t s1_len, size_t s2_len){
int letters1[255] = {};
int letters2[255] = {};
long unsigned int indx = 0;
if(s1_len != s2_len){
return false;
}
for(indx = 0; indx < s1_len; ++indx){
int li1 = static_cast<int>(s1[indx]);
int li2 = static_cast<int>(s2[indx]);
letters1[li1] += 1;
letters2[li2] += 1;
}
for(indx = 0; indx < 255; ++indx){
if (letters1[indx] != letters2[indx]){
return false;
}
}
return true;
}

View File

@@ -0,0 +1,21 @@
#include <iostream>
#include "chapter1.hpp"
/* Prompt
Is Unique: Implement an algorithm to determine if a string
has all unique characters. What if you cannot use additional data
structures?
*/
bool IsUnique(const char* s, int len){
int tracker[255]= {};
for(int i=0; i<len; ++i){
int tracker_index = static_cast<int>(s[i]);
tracker[tracker_index] += 1;
if (tracker[tracker_index] > 1){
return false;
}
}
return true;
}

View File

@@ -0,0 +1,5 @@
chapter1_sources = ['is_unique.cpp', 'check_permutation.cpp']
chapter1_lib = static_library('chapter1',
chapter1_sources)

View File

@@ -0,0 +1,5 @@
#pragma once
#include <iostream>
void reverse_str(char* str);

View File

@@ -0,0 +1,4 @@
chapter12_sources = ['reverse_string.cpp']
chapter12_lib = static_library('chapter12',
chapter12_sources)

View File

@@ -0,0 +1,20 @@
#include "chapter12.hpp"
#include <string.h>
#include <stdlib.h>
/*
Reverse String: Implement a function void reverse( char* str) in C or C++ which reverses
a null-terminated string.
*/
void reverse_str(char *str){
size_t len = strlen(str);
char *tmp = reinterpret_cast<char*>(malloc(len));
strcpy(tmp, str);
for(unsigned int offset = 0; offset < len; ++offset){
str[offset] = tmp[len-offset-1];
}
str[len] = '\0';
free(tmp);
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include <dope/linkedlist.hpp>
// Utility functions
void remove_dups(DopeLinkedList* ll);
void reverse_linkedlist(DopeLinkedList* ll);

View File

@@ -0,0 +1,5 @@
ch2_srcs = ['remove_dups.cpp', 'reverse.cpp']
chapter2_lib = static_library('chapter2',
ch2_srcs,
include_directories: libs_includes)

View File

@@ -0,0 +1,35 @@
#include "chapter2.hpp"
#include <unordered_map>
/*
Remove Dups!
Write code to remove duplicates from an unsorted linked list.
FOLLOW UP
How would you solve this problem if a temporary buffer is not allowed?
*/
void remove_dups(DopeLinkedList* ll){
DopeNode* prev = ll->GetHead();
DopeNode* node = ll->GetHead();
DopeNode* tmp = NULL;
std::unordered_map<int, int> dup_tracker;
int iter_cnt = 0;
while(node->GetNext() != NULL){
if(dup_tracker.count(node->GetData())){
// remove node
prev->SetNext(node->GetNext());
tmp = node;
node = node->GetNext();
tmp->Reset();
} else {
dup_tracker[node->GetData()] += 1;
node = node->GetNext();
if (iter_cnt != 0){
prev = prev->GetNext();
}
}
iter_cnt++;
}
}

32
libs/chapter2/reverse.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include "chapter2.hpp"
#include <stack>
/*
Reverse Linked List
*/
void reverse_linkedlist(DopeLinkedList* ll){
DopeNode* node = ll->GetHead();
DopeNode* prev = nullptr;
std::stack<DopeNode*> s;
int iter_cnt = 0;
s.push(node);
while(node->GetNext() != NULL){
s.push(node);
node = node->GetNext();
iter_cnt++;
}
s.push(node);
prev = s.top();
s.pop();
ll->SetHead(prev);
while(!s.empty()){
node = s.top();
s.pop();
prev->SetNext(node);
prev = node;
}
node->SetNext(nullptr);
}

172
libs/dope/bintree.hpp Normal file
View File

@@ -0,0 +1,172 @@
#pragma once
#include <queue>
template <class T>
class DopeBinTreeNode{
DopeBinTreeNode<T>* left;
DopeBinTreeNode<T>* right;
T data;
public:
DopeBinTreeNode(T data);
~DopeBinTreeNode();
void SetLeft(DopeBinTreeNode<T>* newleft){left = newleft;}
void SetRight(DopeBinTreeNode<T>* newright){right = newright;}
DopeBinTreeNode<T>* GetLeft(){return left;}
DopeBinTreeNode<T>* GetRight(){return right;}
T GetData(){return data;}
};
template <class T>
class DopeBinTree{
DopeBinTreeNode<T>* root;
T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out);
T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out);
T* RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out);
public:
DopeBinTree(T data);
DopeBinTree();
~DopeBinTree();
void insert(T data);
bool isEmpty();
DopeBinTreeNode<T>* getRoot(){return root;}
void RecPreOrderTraversalArray(T* array);
void RecInOrderTraversalArray(T* array);
void RecPostOrderTraversalArray(T* array);
};
// Implementations ___________________________________________________
template <class T>
DopeBinTreeNode<T>::DopeBinTreeNode(T node_data):
left(nullptr),
right(nullptr),
data(node_data)
{
}
template <class T>
DopeBinTreeNode<T>::~DopeBinTreeNode(){
delete left;
delete right;
}
template <class T>
DopeBinTree<T>::DopeBinTree(T data){
root = new DopeBinTreeNode<T>(data);
}
template <class T>
DopeBinTree<T>::DopeBinTree():
root(nullptr)
{
}
template <class T>
DopeBinTree<T>::~DopeBinTree(){
if (root != nullptr){
delete root;
}
}
template <class T>
// Insert Breadth first
void DopeBinTree<T>::insert(T data){
DopeBinTreeNode<T>* current_node = root;
if (root == nullptr){
root = new DopeBinTreeNode<T>(data);
} else {
auto new_node = new DopeBinTreeNode<T>(data);
// Breadth first traversal
std::queue<DopeBinTreeNode<T>*> q;
q.push(root);
while(!q.empty()){
current_node = q.front();
q.pop();
if(current_node->GetLeft()){
q.push(current_node->GetLeft());
} else {
current_node->SetLeft(new_node);
break;
}
if(current_node->GetRight()){
q.push(current_node->GetRight());
} else {
current_node->SetRight(new_node);
break;
}
}
}
}
template <class T>
bool DopeBinTree<T>::isEmpty(){
if(root == nullptr){
return true;
} else {
return false;
}
}
template <class T>
T* DopeBinTree<T>::RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out){
if (node == nullptr){
return out--;
}
*out = node->GetData();
out++;
out = RecPreOrderTraversal(node->GetLeft(), out);
out = RecPreOrderTraversal(node->GetRight(), out);
return out;
}
template <class T>
T* DopeBinTree<T>::RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out){
if (node == nullptr){
return out--;
}
out = RecInOrderTraversal(node->GetLeft(), out);
*out = node->GetData();
out++;
out = RecInOrderTraversal(node->GetRight(), out);
return out;
}
template <class T>
T* DopeBinTree<T>::RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){
if (node == nullptr){
return out--;
}
out = RecPostOrderTraversal(node->GetLeft(), out);
out = RecPostOrderTraversal(node->GetRight(), out);
*out = node->GetData();
out++;
return out;
}
template <class T>
void DopeBinTree<T>::RecPreOrderTraversalArray(T* array){
int index = 0;
DopeBinTreeNode<T>* node = root;
RecPreOrderTraversal(node, &array[index]);
}
template <class T>
void DopeBinTree<T>::RecInOrderTraversalArray(T* array){
int index = 0;
DopeBinTreeNode<T>* node = root;
RecInOrderTraversal(node, &array[index]);
}
template <class T>
void DopeBinTree<T>::RecPostOrderTraversalArray(T* array){
int index = 0;
DopeBinTreeNode<T>* node = root;
RecPostOrderTraversal(node, &array[index]);
}

56
libs/dope/linkedlist.cpp Normal file
View File

@@ -0,0 +1,56 @@
#include "linkedlist.hpp"
DopeLinkedList::DopeLinkedList(){
for(int i = 0; i < MAX_DOPE_NODES; ++i){
nodes[i].Reset();
}
head = &nodes[0];
}
DopeNode::DopeNode(int init_data){
data = init_data;
next = NULL;
state = NodeState::UnInitialized;
}
DopeNode::DopeNode(){
Reset();
}
void DopeNode::Reset(){
this->data = 0;
this->next = NULL;
this->state = NodeState::UnInitialized;
}
void DopeLinkedList::AppendData(int init_data){
DopeNode* new_node = head;
DopeNode* node = head;
// Find next free slot and allocate it for the new node
for(int i=0; i < MAX_DOPE_NODES; ++i){
if(nodes[i].GetState() == NodeState::UnInitialized){
new_node = &nodes[i];
new_node->SetNext(NULL);
new_node->SetState(NodeState::Initialized);
new_node->SetData(init_data);
break;
}
}
if(head == new_node){
// Just set first node, nothing else to do
return;
}
// Find last node in linked list
if ((head->GetNext() == NULL) && (head->GetState() == NodeState::Initialized)){
// Special case, only one node so far
head->SetNext(new_node);
} else {
while(node->GetNext() != NULL){
node = node->GetNext();
}
node->SetNext(new_node);
}
}

37
libs/dope/linkedlist.hpp Normal file
View File

@@ -0,0 +1,37 @@
#pragma once
#include<stdlib.h>
#define MAX_DOPE_NODES 255
typedef enum NodeState_E{
UnInitialized,
Initialized
} NodeState;
class DopeNode {
int data;
DopeNode* next;
NodeState state;
public:
DopeNode(int data);
DopeNode();
DopeNode* GetNext(){return next;}
NodeState GetState(){return state;}
int GetData(){return data;}
void SetNext(DopeNode* node){next = node;}
void SetState(NodeState new_state){state = new_state;}
void SetData(int new_data){data = new_data;}
void Reset();
};
class DopeLinkedList {
DopeNode nodes[MAX_DOPE_NODES];
DopeNode* head;
public:
DopeLinkedList();
void AppendData(int init_data);
DopeNode* GetHead(){return head;}
void SetHead(DopeNode* new_head){head = new_head;}
};

3
libs/dope/meson.build Normal file
View File

@@ -0,0 +1,3 @@
dope_srcs = ['linkedlist.cpp']
dope_lib = static_library('dope', dope_srcs)

1
libs/dope/queues.cpp Normal file
View File

@@ -0,0 +1 @@
#include <dope/queues.hpp>

1
libs/dope/queues.hpp Normal file
View File

@@ -0,0 +1 @@
#pragma once

59
libs/dope/stacks.hpp Normal file
View File

@@ -0,0 +1,59 @@
#pragma once
#include <stdlib.h>
template <class T, size_t S>
class DopeStack{
static const size_t size = S;
T stack[S];
T* head;
size_t occupancy;
public:
DopeStack();
T pop();
void push(T item);
T peek();
size_t getOccupancy(){return occupancy;}
bool isEmpty();
};
// Implementation ____________________________________________________
template <class T, size_t S>
DopeStack<T, S>::DopeStack():
head (&stack[0]),
occupancy(0)
{
}
template <class T, size_t S>
T DopeStack<T, S>::pop(){
T ret = *head;
if(head != &stack[0]){
head--;
}
occupancy--;
return ret;
}
template <class T, size_t S>
void DopeStack<T, S>::push(T item){
if(occupancy != 0){
head++;
}
*head = item;
occupancy++;
}
template <class T, size_t S>
T DopeStack<T, S>::peek(){
return *head;
}
template <class T, size_t S>
bool DopeStack<T, S>::isEmpty(){
return (occupancy == 0);
}

6
libs/meson.build Normal file
View File

@@ -0,0 +1,6 @@
libs_includes = include_directories('.')
subdir('dope')
subdir('chapter1')
subdir('chapter2')
subdir('chapter12')