Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • fal/code-samples/comp290
1 result
Show changes
Commits on Source (9)
...@@ -4,3 +4,4 @@ build/ ...@@ -4,3 +4,4 @@ build/
# IDE settings don't need to be stored, we're cmake # IDE settings don't need to be stored, we're cmake
.idea/ .idea/
cmake-build-*/ cmake-build-*/
.vs/
...@@ -7,6 +7,11 @@ cmake_minimum_required(VERSION 3.13) ...@@ -7,6 +7,11 @@ cmake_minimum_required(VERSION 3.13)
# sudo apt install libbenchmark-dev (Ubuntu, you'll also need cmake and build-essential) # sudo apt install libbenchmark-dev (Ubuntu, you'll also need cmake and build-essential)
# ?? Mac # ?? Mac
if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "")
endif()
project(comp290_worksheets) project(comp290_worksheets)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
...@@ -32,3 +37,6 @@ target_sources(counting ...@@ -32,3 +37,6 @@ target_sources(counting
# COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/labs/counting/generate.py # COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/labs/counting/generate.py
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} # WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
#) #)
# Lab 3
add_subdirectory(labs/trees)
#include <vector>
#include <map>
#include <iostream>
struct Arc {
char to;
float weight;
};
constexpr float NOT_FOUND = 0.0F;
class Graph {
public:
void addArc(char from, char to, float weight = 1.0F) {
auto& links = m_list[from];
links.push_back({ .to = to, .weight = weight });
}
std::vector<char> getArcs(char from) {
std::vector<char> arcs;
for ( auto& arc : m_list.at(from) ) {
arcs.push_back( arc.to );
}
return arcs;
}
float getWeight(char from, char to) {
auto& links = m_list.at(from);
for (auto& link : links) {
if ( link.to == to ) {
return link.weight;
}
}
return NOT_FOUND;
}
inline bool hasVertex(char vertex) const {
return m_list.find( vertex ) != m_list.end();
}
private:
// there is a better structure we can use
std::map<char, std::vector<Arc>> m_list;
};
int main( int argc, char* argv[] ) {
Graph graph;
graph.addArc('a', 'b');
graph.addArc('b', 'a');
std::cout << graph.getWeight('a', 'b') << std::endl;
std::cout << graph.hasVertex('d') << std::endl;
return 0;
}
\ No newline at end of file
#ifndef LABS_TREES_TREES_HPP
#define LABS_TREES_TREES_HPP
#include <ostream>
struct Node {
int value;
Node* left = nullptr;
Node* right = nullptr;
inline bool isLeaf() const {
return left == nullptr && right == nullptr;
}
};
// unbalanced
void add_node(Node* root, int newValue);
bool search(const Node* root, int searchValue);
// utility methods
void print_tree(std::ostream& out, Node* root, int depth=0);
void print_tree_dia(std::ostream& out, Node* root);
#endif // LABS_TREES_TREES_HPP
\ No newline at end of file
# Trees lab script
add_executable(trees ${SOURCE_FILES})
target_include_directories(trees PRIVATE ../../include)
target_sources(trees
PRIVATE
main.cpp
tree.cpp
)
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include "labs/trees/trees.hpp"
static void build_static_tree() {
Node* root = new Node();
root->value = 5;
// construct a tree
add_node(root, 6);
add_node(root, 3);
add_node(root, 2);
add_node(root, 1);
add_node(root, -50);
add_node(root, 10);
// print out diagram
std::ofstream diagram;
diagram.open("tree.dia", std::ios::out);
print_tree_dia(diagram, root);
diagram.close();
}
static Node* build_tree_interactive() {
// build phase
std::string treeVal;
Node* root = nullptr;
while (treeVal != "done") {
try {
std::cin >> treeVal;
if (treeVal == "done") {
break;
}
int value = std::stoi(treeVal);
if (root == nullptr) {
root = new Node();
root->value = value;
}
else {
add_node(root, value);
}
}
catch (std::invalid_argument&) {
std::cout << "that is not a valid number" << std::endl;
}
}
return root;
}
void search_tree_interactive(const Node* root) {
// build phase
std::string treeVal;
std::cout << "search mode, enter number or done." << std::endl;
while (treeVal != "done") {
try {
std::cin >> treeVal;
if (treeVal == "done") {
break;
}
int value = std::stoi(treeVal);
bool result = search(root, value);
if (result) {
std::cout << value << " is located in the tree" << std::endl;
} else {
std::cout << value << " is *not* located in the tree" << std::endl;
}
}
catch (std::invalid_argument&) {
std::cout << "that is not a valid number" << std::endl;
}
}
}
static void interactive_tree() {
std::cout << "TreeBuilder v1.0" << std::endl;
std::cout << "type numbers, then done to ask questions" << std::endl;
Node* root = build_tree_interactive();
search_tree_interactive(root);
delete root;
}
int main(int argc, const char* argv[]) {
interactive_tree();
}
#include "labs/trees/trees.hpp"
#include <iostream>
void add_node(Node* parent, int newValue) {
if (parent->value > newValue) {
if (parent->left == nullptr) {
parent->left = new Node();
parent->left->value = newValue;
}
else {
add_node(parent->left, newValue);
}
}
else {
if (parent->right == nullptr) {
parent->right = new Node();
parent->right->value = newValue;
}
else {
add_node(parent->right, newValue);
}
}
}
bool search(const Node* root, int value) {
// TODO there is a bug in this code, what is it?
// use the unit test results to help you find it
// vcpkg instlal gtest:x64-windows
if (root == nullptr) {
return false;
}
if (root->value == value) {
return true;
}
else if (root->value < value) {
return search(root->left, value);
}
else {
return search(root->right, value);
}
}
void print_tree(std::ostream& out, Node* root, int depth) {
for (int i = 0; i < depth; ++i) {
out << '\t';
}
if (root == nullptr) {
out << "null" << std::endl;
return;
}
std::cout << root->value << std::endl;
if (!root->isLeaf()) {
print_tree(out, root->left, depth + 1);
print_tree(out, root->right, depth + 1);
}
}
static void print_tree_dia_node(std::ostream& out, Node* node) {
if (node->isLeaf()) {
return;
}
if (node->left != nullptr) {
out << "\t" << node->value << " -> " << node->left->value << "[label=l];" << std::endl;
print_tree_dia_node(out, node->left);
} else {
out << "\t" << node->value << " -> l" << node->value << "[label=l];" << std::endl;
out << "\tl" << node->value << "[label=N];" << std::endl;
}
if (node->right != nullptr) {
out << "\t" << node->value << " -> " << node->right->value << "[label=r];" << std::endl;
print_tree_dia_node(out, node->right);
} else {
out << "\t" << node->value << " -> r" << node->value << "[label=r];" << std::endl;
out << "\tr" << node->value << "[label=N];" << std::endl;
}
}
void print_tree_dia(std::ostream& out, Node* root) {
out << "digraph tree { " << std::endl;
print_tree_dia_node(out, root);
out << "}" << std::endl;
}
\ No newline at end of file
...@@ -2,4 +2,9 @@ find_package(benchmark) ...@@ -2,4 +2,9 @@ find_package(benchmark)
if ( benchmark_FOUND ) if ( benchmark_FOUND )
add_subdirectory( sorting ) add_subdirectory( sorting )
add_subdirectory( counting ) add_subdirectory( counting )
endif()
find_package(GTest REQUIRED)
if ( GTest_FOUND )
add_subdirectory( trees )
endif() endif()
\ No newline at end of file
add_executable(tree-unit)
target_link_libraries(tree-unit GTest::GTest)
target_include_directories(tree-unit PRIVATE ../../../include)
target_sources(tree-unit
PRIVATE
tree_unit.cpp
../../../labs/trees/tree.cpp
)
\ No newline at end of file
#include <labs/trees/trees.hpp>
#include <gtest/gtest.h>
TEST(BinaryTree, TestAddBalanced) {
Node* root = new Node();
root->value = 42;
add_node(root, 7);
add_node(root, 100);
EXPECT_NE(root->left, nullptr);
EXPECT_NE(root->right, nullptr);
ASSERT_EQ(7, root->left->value);
ASSERT_EQ(100, root->right->value);
}
TEST(BinaryTree, TestAddUnbalancedLeft) {
Node* root = new Node();
root->value = 42;
add_node(root, 7);
add_node(root, 4);
EXPECT_NE(root->left, nullptr);
EXPECT_NE(root->left->left, nullptr);
// right branches should be null
EXPECT_EQ(root->right, nullptr);
EXPECT_EQ(root->left->right, nullptr);
ASSERT_EQ(7, root->left->value);
ASSERT_EQ(4, root->left->left->value);
}
TEST(BinaryTree, TestAddUnbalancedRight) {
Node* root = new Node();
root->value = 42;
add_node(root, 50);
add_node(root, 100);
// left nodes should be null
EXPECT_EQ(root->left, nullptr);
EXPECT_EQ(root->right->left, nullptr);
// right branches should not be null
EXPECT_NE(root->right, nullptr);
EXPECT_NE(root->right->right, nullptr);
ASSERT_EQ(50, root->right->value);
ASSERT_EQ(100, root->right->right->value);
}
TEST(BinaryTree, TestAddUnbalancedRightLeft) {
Node* root = new Node();
root->value = 42;
add_node(root, 50);
add_node(root, 47);
// nodes should be null
EXPECT_EQ(root->left, nullptr);
EXPECT_EQ(root->right->right, nullptr);
// right branches should not be null
EXPECT_NE(root->right, nullptr);
EXPECT_NE(root->right->left, nullptr);
ASSERT_EQ(50, root->right->value);
ASSERT_EQ(47, root->right->left->value);
}
TEST(BinaryTree, TestAddUnbalancedLeftRight) {
// TODO write a test case that places a value in root->left->right
// you can use TestAddUnbalancedRightLeft to help you
}
#ifdef TREE_PART_2
//
// PART 2
// enable this by #define TREE_PART_2
// in the tree header
//
static Node* build_test_tree() {
Node* root = new Node();
root->value = 200;
add_node(root, 290);
add_node(root, 250);
add_node(root, 110);
add_node(root, 120);
return root;
}
TEST(BinaryTree, TestSearchRoot) {
Node* root = build_test_tree();
ASSERT_EQ(true, search(root, 200));
delete root;
}
TEST(BinaryTree, TestSearchRootMissing) {
Node* root = build_test_tree();
ASSERT_EQ(false, search(root, 310));
delete root;
}
TEST(BinaryTree, TestSearchRootNull) {
ASSERT_EQ(false, search(nullptr , 42));
}
TEST(BinaryTree, TestSearchLeft) {
Node* root = build_test_tree();
ASSERT_EQ(true, search(root, 110));
delete root;
}
TEST(BinaryTree, TestSearchRight) {
Node* root = build_test_tree();
ASSERT_EQ(true, search(root, 290));
delete root;
}
#endif
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
\ No newline at end of file