Initial commit of code for dopelib, and ch 1, 2, and 12
This commit is contained in:
parent
11601352d3
commit
afbf4c2f7e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
/.cache/
|
/.cache/
|
||||||
/devbox.lock
|
/devbox.lock
|
||||||
/subprojects/cpputest-4.0/
|
/subprojects/cpputest-4.0/
|
||||||
|
/subprojects/packagecache/
|
||||||
|
12
devbox.json
Normal file
12
devbox.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
|
||||||
|
"packages": [
|
||||||
|
"meson@latest",
|
||||||
|
"gcc14@latest"
|
||||||
|
],
|
||||||
|
"shell": {
|
||||||
|
"init_hook": [
|
||||||
|
"echo 'Welcome to the DSA Learning Zone!' > /dev/null"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
6
libs/chapter1/chapter1.hpp
Normal file
6
libs/chapter1/chapter1.hpp
Normal 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);
|
35
libs/chapter1/check_permutation.cpp
Normal file
35
libs/chapter1/check_permutation.cpp
Normal 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;
|
||||||
|
}
|
21
libs/chapter1/is_unique.cpp
Normal file
21
libs/chapter1/is_unique.cpp
Normal 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;
|
||||||
|
}
|
5
libs/chapter1/meson.build
Normal file
5
libs/chapter1/meson.build
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
chapter1_sources = ['is_unique.cpp', 'check_permutation.cpp']
|
||||||
|
|
||||||
|
chapter1_lib = static_library('chapter1',
|
||||||
|
chapter1_sources)
|
5
libs/chapter12/chapter12.hpp
Normal file
5
libs/chapter12/chapter12.hpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void reverse_str(char* str);
|
4
libs/chapter12/meson.build
Normal file
4
libs/chapter12/meson.build
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
chapter12_sources = ['reverse_string.cpp']
|
||||||
|
|
||||||
|
chapter12_lib = static_library('chapter12',
|
||||||
|
chapter12_sources)
|
20
libs/chapter12/reverse_string.cpp
Normal file
20
libs/chapter12/reverse_string.cpp
Normal 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);
|
||||||
|
}
|
7
libs/chapter2/chapter2.hpp
Normal file
7
libs/chapter2/chapter2.hpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dope/linkedlist.hpp>
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
void remove_dups(DopeLinkedList* ll);
|
||||||
|
void reverse_linkedlist(DopeLinkedList* ll);
|
5
libs/chapter2/meson.build
Normal file
5
libs/chapter2/meson.build
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
ch2_srcs = ['remove_dups.cpp', 'reverse.cpp']
|
||||||
|
|
||||||
|
chapter2_lib = static_library('chapter2',
|
||||||
|
ch2_srcs,
|
||||||
|
include_directories: libs_includes)
|
35
libs/chapter2/remove_dups.cpp
Normal file
35
libs/chapter2/remove_dups.cpp
Normal 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
32
libs/chapter2/reverse.cpp
Normal 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
172
libs/dope/bintree.hpp
Normal 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
56
libs/dope/linkedlist.cpp
Normal 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
37
libs/dope/linkedlist.hpp
Normal 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
3
libs/dope/meson.build
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dope_srcs = ['linkedlist.cpp']
|
||||||
|
|
||||||
|
dope_lib = static_library('dope', dope_srcs)
|
1
libs/dope/queues.cpp
Normal file
1
libs/dope/queues.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include <dope/queues.hpp>
|
1
libs/dope/queues.hpp
Normal file
1
libs/dope/queues.hpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#pragma once
|
59
libs/dope/stacks.hpp
Normal file
59
libs/dope/stacks.hpp
Normal 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
6
libs/meson.build
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
libs_includes = include_directories('.')
|
||||||
|
|
||||||
|
subdir('dope')
|
||||||
|
subdir('chapter1')
|
||||||
|
subdir('chapter2')
|
||||||
|
subdir('chapter12')
|
9
meson.build
Normal file
9
meson.build
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
project('CrackingTheCodingInterview', 'cpp',
|
||||||
|
version: '0.1',
|
||||||
|
default_options : [
|
||||||
|
'warning_level=3',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
subdir('libs')
|
||||||
|
subdir('tests')
|
13
subprojects/cpputest.wrap
Normal file
13
subprojects/cpputest.wrap
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = cpputest-4.0
|
||||||
|
source_url = https://github.com/cpputest/cpputest/archive/v4.0.tar.gz
|
||||||
|
source_filename = cpputest-4.0.tar.gz
|
||||||
|
source_hash = 0b66d20661f232d2a6af124c4455c8ccc9a4ce72d29f6ad4877eb385faaf5108
|
||||||
|
patch_filename = cpputest_4.0-3_patch.zip
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/cpputest_4.0-3/get_patch
|
||||||
|
patch_hash = 75d9e997e246884df77db2c295e465f3d25a84497a337691017c86c24a0ebf93
|
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/cpputest_4.0-3/cpputest-4.0.tar.gz
|
||||||
|
wrapdb_version = 4.0-3
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
cpputest = cpputest_dep
|
11
tests/meson.build
Normal file
11
tests/meson.build
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
cpputest_project = subproject('cpputest', required: true)
|
||||||
|
cpputest = cpputest_project.get_variable('cpputest_dep')
|
||||||
|
|
||||||
|
test_exe = executable(
|
||||||
|
'CrackingTheCodingInvterviewVerification',
|
||||||
|
sources: 'test.cpp',
|
||||||
|
dependencies: cpputest,
|
||||||
|
link_with: [chapter1_lib, chapter2_lib, chapter12_lib, dope_lib],
|
||||||
|
include_directories: libs_includes)
|
||||||
|
|
||||||
|
test('Cracking The Coding Interview Test', test_exe)
|
189
tests/test.cpp
Normal file
189
tests/test.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#include <CppUTest/CommandLineTestRunner.h>
|
||||||
|
#include <CppUTest/TestHarness.h>
|
||||||
|
|
||||||
|
#include <chapter1/chapter1.hpp>
|
||||||
|
#include <chapter2/chapter2.hpp>
|
||||||
|
#include <chapter12/chapter12.hpp>
|
||||||
|
#include <dope/linkedlist.hpp>
|
||||||
|
#include <dope/stacks.hpp>
|
||||||
|
#include <dope/bintree.hpp>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Chapter 1: Arrays _________________________________________________
|
||||||
|
|
||||||
|
TEST_GROUP(ChapterOne){};
|
||||||
|
|
||||||
|
TEST(ChapterOne, IsUnique){
|
||||||
|
auto const t1 = IsUnique("aabbcc", 6);
|
||||||
|
auto const t2 = IsUnique("abcdef", 6);
|
||||||
|
CHECK_FALSE(t1);
|
||||||
|
CHECK(t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChapterOne, CheckPermutations){
|
||||||
|
const auto s1 = "Hello";
|
||||||
|
const auto s2 = "olleH";
|
||||||
|
const auto s3 = "Holaa";
|
||||||
|
|
||||||
|
auto const t1 = CheckPermutation(s1, s2, strlen(s1), strlen(s2));
|
||||||
|
auto const t2 = CheckPermutation(s1, s3, strlen(s1), strlen(s3));
|
||||||
|
CHECK(t1);
|
||||||
|
CHECK_FALSE(t2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chapter 2: Linked Lists ___________________________________________
|
||||||
|
|
||||||
|
TEST_GROUP(ChapterTwo){};
|
||||||
|
TEST(ChapterTwo, RemoveDups){
|
||||||
|
auto dll = new DopeLinkedList();
|
||||||
|
dll->AppendData(1);
|
||||||
|
dll->AppendData(2);
|
||||||
|
dll->AppendData(2);
|
||||||
|
dll->AppendData(3);
|
||||||
|
|
||||||
|
remove_dups(dll);
|
||||||
|
auto node = dll->GetHead();
|
||||||
|
|
||||||
|
CHECK_EQUAL(1, node->GetData());
|
||||||
|
node = node->GetNext();
|
||||||
|
CHECK_EQUAL(2, node->GetData());
|
||||||
|
node = node->GetNext();
|
||||||
|
CHECK_EQUAL(3, node->GetData());
|
||||||
|
delete dll;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChapterTwo, Reverse){
|
||||||
|
auto dll = new DopeLinkedList();
|
||||||
|
dll->AppendData(1);
|
||||||
|
dll->AppendData(2);
|
||||||
|
dll->AppendData(3);
|
||||||
|
dll->AppendData(100);
|
||||||
|
|
||||||
|
auto node = dll->GetHead();
|
||||||
|
CHECK_EQUAL(1, node->GetData());
|
||||||
|
reverse_linkedlist(dll);
|
||||||
|
node = dll->GetHead();
|
||||||
|
CHECK_EQUAL(100, node->GetData());
|
||||||
|
node = node->GetNext();
|
||||||
|
CHECK_EQUAL(3, node->GetData());
|
||||||
|
node = node->GetNext();
|
||||||
|
CHECK_EQUAL(2, node->GetData());
|
||||||
|
node = node->GetNext();
|
||||||
|
CHECK_EQUAL(1, node->GetData());
|
||||||
|
CHECK_EQUAL(nullptr, node->GetNext());
|
||||||
|
|
||||||
|
delete dll;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chapter 3: Stacks and Queues ______________________________________
|
||||||
|
|
||||||
|
TEST_GROUP(ChapterThree){};
|
||||||
|
TEST(ChapterThree, StackMin){
|
||||||
|
auto stack = new DopeStack<int, 20>();
|
||||||
|
stack->push(10);
|
||||||
|
stack->push(25);
|
||||||
|
stack->push(42);
|
||||||
|
stack->push(100);
|
||||||
|
stack->push(2);
|
||||||
|
|
||||||
|
CHECK_EQUAL(2, stack->peek());
|
||||||
|
CHECK_EQUAL(2, stack->pop());
|
||||||
|
CHECK_EQUAL(100, stack->pop());
|
||||||
|
CHECK_FALSE(stack->isEmpty());
|
||||||
|
(void)stack->pop();
|
||||||
|
(void)stack->pop();
|
||||||
|
(void)stack->pop();
|
||||||
|
CHECK_TRUE(stack->isEmpty());
|
||||||
|
delete stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chapter 4: Trees __________________________________________________
|
||||||
|
TEST_GROUP(ChapterFour){};
|
||||||
|
TEST(ChapterFour, BinaryTrees){
|
||||||
|
auto btree = DopeBinTree<int>();
|
||||||
|
btree.insert(1);
|
||||||
|
btree.insert(2);
|
||||||
|
btree.insert(3);
|
||||||
|
btree.insert(4);
|
||||||
|
btree.insert(5);
|
||||||
|
btree.insert(6);
|
||||||
|
btree.insert(7);
|
||||||
|
btree.insert(8);
|
||||||
|
|
||||||
|
|
||||||
|
auto root = btree.getRoot();
|
||||||
|
CHECK_EQUAL(1, root->GetData());
|
||||||
|
CHECK_EQUAL(2, root->GetLeft()->GetData());
|
||||||
|
CHECK_EQUAL(3, root->GetRight()->GetData());
|
||||||
|
CHECK_EQUAL(4, root->GetLeft()->GetLeft()->GetData());
|
||||||
|
CHECK_EQUAL(5, root->GetLeft()->GetRight()->GetData());
|
||||||
|
CHECK_EQUAL(6, root->GetRight()->GetLeft()->GetData());
|
||||||
|
CHECK_EQUAL(7, root->GetRight()->GetRight()->GetData());
|
||||||
|
CHECK_EQUAL(8, root->GetLeft()->GetLeft()->GetLeft()->GetData());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChapterFour, TreeTraversal){
|
||||||
|
auto btree = DopeBinTree<int>();
|
||||||
|
btree.insert(1); // Root
|
||||||
|
btree.insert(2);
|
||||||
|
btree.insert(3);
|
||||||
|
btree.insert(4);
|
||||||
|
btree.insert(5);
|
||||||
|
btree.insert(6);
|
||||||
|
btree.insert(7);
|
||||||
|
|
||||||
|
int array[10] = {};
|
||||||
|
|
||||||
|
btree.RecPreOrderTraversalArray(array);
|
||||||
|
CHECK_EQUAL(1, array[0]);
|
||||||
|
CHECK_EQUAL(2, array[1]);
|
||||||
|
CHECK_EQUAL(4, array[2]);
|
||||||
|
CHECK_EQUAL(5, array[3]);
|
||||||
|
CHECK_EQUAL(3, array[4]);
|
||||||
|
CHECK_EQUAL(6, array[5]);
|
||||||
|
CHECK_EQUAL(7, array[6]);
|
||||||
|
|
||||||
|
std::fill(array, array+10, 0);
|
||||||
|
|
||||||
|
btree.RecInOrderTraversalArray(array);
|
||||||
|
CHECK_EQUAL(4, array[0]);
|
||||||
|
CHECK_EQUAL(2, array[1]);
|
||||||
|
CHECK_EQUAL(5, array[2]);
|
||||||
|
CHECK_EQUAL(1, array[3]);
|
||||||
|
CHECK_EQUAL(6, array[4]);
|
||||||
|
CHECK_EQUAL(3, array[5]);
|
||||||
|
CHECK_EQUAL(7, array[6]);
|
||||||
|
|
||||||
|
std::fill(array, array+10, 0);
|
||||||
|
|
||||||
|
btree.RecPostOrderTraversalArray(array);
|
||||||
|
CHECK_EQUAL(4, array[0]);
|
||||||
|
CHECK_EQUAL(5, array[1]);
|
||||||
|
CHECK_EQUAL(2, array[2]);
|
||||||
|
CHECK_EQUAL(6, array[3]);
|
||||||
|
CHECK_EQUAL(7, array[4]);
|
||||||
|
CHECK_EQUAL(3, array[5]);
|
||||||
|
CHECK_EQUAL(1, array[6]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ChapterFour, MinHeap){
|
||||||
|
auto btree = DopeBinTree<int>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chapter 12: C/C++ _________________________________________________
|
||||||
|
|
||||||
|
TEST_GROUP(ChapterTwelve){};
|
||||||
|
TEST(ChapterTwelve, ReverseString){
|
||||||
|
char s1[] = "Hello";
|
||||||
|
reverse_str(s1);
|
||||||
|
STRCMP_EQUAL("olleH", s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int ac, char** av){
|
||||||
|
return CommandLineTestRunner::RunAllTests(ac, av);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user