mirror of
https://git.adityakumar.xyz/data-structures.git
synced 2024-11-12 22:29:45 +00:00
add cpp array and list
This commit is contained in:
parent
a5f0cb8f4c
commit
e326c0cd1a
6 changed files with 447 additions and 0 deletions
17
cpp/build_array.cpp
Normal file
17
cpp/build_array.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <iostream>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
template<typename... Args>
|
||||
auto build_array(Args&&... args) -> std::array<typename std::common_type<Args...>::type, sizeof...(args)> {
|
||||
using commonType = typename std::common_type<Args...>::type; // Create array
|
||||
return {std::forward<commonType>(args)...};
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto data {build_array(1, 0u, 'a', 3.2f, false)};
|
||||
for (const auto& i : data) std::cout << i << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
124
cpp/dynamic_array.cpp
Normal file
124
cpp/dynamic_array.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename T>
|
||||
class dynamic_array {
|
||||
T* data;
|
||||
size_t n;
|
||||
|
||||
public:
|
||||
dynamic_array(int n) {
|
||||
this -> n = n;
|
||||
data = new T[n];
|
||||
}
|
||||
|
||||
dynamic_array(const dynamic_array<T>& other) {
|
||||
n = other.n;
|
||||
data = new T[n];
|
||||
|
||||
/* We perform a deep copy */
|
||||
for (int i = 0; i < n; ++i) data[i] = other[i];
|
||||
}
|
||||
|
||||
T& operator[](int index) {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
const T& operator[](int index) const {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T& at(int index) {
|
||||
if (index < n) return data[index];
|
||||
throw "Index out of range";
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return n;
|
||||
}
|
||||
|
||||
~dynamic_array() {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
T* begin() {
|
||||
return data;
|
||||
}
|
||||
|
||||
const T* begin() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
T* end() {
|
||||
return data + n;
|
||||
}
|
||||
|
||||
const T* end() const {
|
||||
return data + n;
|
||||
}
|
||||
|
||||
friend dynamic_array<T> operator+(const dynamic_array<T>& arr1, dynamic_array<T>& arr2) {
|
||||
dynamic_array<T> result(arr1.size() + arr2.size());
|
||||
std::copy(arr1.begin(), arr1.end(), result.begin());
|
||||
std::copy(arr2.begin(), arr2.end(), result.begin() + arr1.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string to_string(const std::string& sep = ", ") {
|
||||
if (n == 0) return " ";
|
||||
std::ostringstream os;
|
||||
os << data[0];
|
||||
|
||||
for (int i = 1; i < n; ++i) os << sep << data[i];
|
||||
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
struct student {
|
||||
std::string name {};
|
||||
int standard {};
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const student& s) {
|
||||
return (os << "[Name: " << s.name << ", Standard: " << s.standard << "]");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int nStudents {};
|
||||
std::cout << "Enter number of students in class 1: ";
|
||||
std::cin >> nStudents;
|
||||
|
||||
dynamic_array<student> class1(nStudents);
|
||||
for (int i = 0; i < nStudents; ++i) {
|
||||
std::cout << "Enter name and class of student " << i + 1 << ": ";
|
||||
std::string name {};
|
||||
int standard {};
|
||||
std::cin >> name >> standard;
|
||||
class1[i] = student{name, standard};
|
||||
}
|
||||
|
||||
// Now, let's try to access the student out of range in the array
|
||||
try {
|
||||
class1[nStudents] = student{"John", 8}; // No exception, indefined bahviour
|
||||
std::cout << "class1 student set out fo range without exception" << std::endl;
|
||||
class1.at(nStudents) = student{"John", 8}; // Will throw exception
|
||||
}
|
||||
catch(...) {
|
||||
std::cout << "Exception caught" << std::endl;
|
||||
}
|
||||
|
||||
auto class2 = class1; // Deep copy
|
||||
|
||||
std::cout << "Second class initialized usnig first array: " << class2.to_string() << std::endl;
|
||||
auto class3 = class1 + class2; // Combines both classes and creates a bigger one
|
||||
|
||||
std::cout << "Combined class: ";
|
||||
std::cout << class3.to_string() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
122
cpp/dynamic_array_new.cpp
Normal file
122
cpp/dynamic_array_new.cpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
template<class T> class dynamic_array {
|
||||
private:
|
||||
std::shared_ptr<T> data {};
|
||||
size_t n {};
|
||||
|
||||
public:
|
||||
dynamic_array(size_t n) {
|
||||
this -> n = n;
|
||||
data = std::make_shared<T[]>(n);
|
||||
}
|
||||
|
||||
dynamic_array(const dynamic_array<T>& other) {
|
||||
n = other.n;
|
||||
data = std::make_shared<T[]>(n);
|
||||
|
||||
/* Here we perform a deep copy */
|
||||
for (size_t i {}; i < n; ++i) data[i] = other[i];
|
||||
}
|
||||
|
||||
T& operator[](int index) {
|
||||
return data.get() + index;
|
||||
}
|
||||
|
||||
const T& operator[](int index) const {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T& at(size_t index) {
|
||||
if (index < n) return data[index];
|
||||
throw "Index out of range";
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return n;
|
||||
}
|
||||
|
||||
~dynamic_array() = default;
|
||||
|
||||
std::shared_ptr<T> begin() {
|
||||
return data;
|
||||
}
|
||||
|
||||
const std::shared_ptr<T> begin() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
std::shared_ptr<T> end() {
|
||||
return data + n;
|
||||
}
|
||||
|
||||
const std::shared_ptr<T> end() const {
|
||||
return data + n;
|
||||
}
|
||||
|
||||
friend dynamic_array<T> operator+(const dynamic_array<T>& arr1, dynamic_array<T>& arr2) {
|
||||
dynamic_array<T> result(arr1.size() + arr2.size());
|
||||
std::copy(arr1.begin(), arr1.end(), result.begin());
|
||||
std::copy(arr2.begin(), arr2.end(), result.begin() + arr1.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string to_string(const std::string& sep = ", ") {
|
||||
if (n == 0) return "";
|
||||
std::ostringstream os {};
|
||||
os << data.get();
|
||||
|
||||
for (size_t i {1}; i < n; ++i) os << sep << data.get() + i;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
struct student {
|
||||
std::string name {};
|
||||
size_t standard {};
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const student& s) {
|
||||
return (os << "[Name: " << s.name << ", Standard: " << s.standard << "]");
|
||||
}
|
||||
|
||||
int main() {
|
||||
size_t nStudents {};
|
||||
std::cout << "Enter number of students in class 1: ";
|
||||
std::cin >> nStudents;
|
||||
|
||||
dynamic_array<student> class1(nStudents);
|
||||
for (size_t i {}; i < nStudents; ++i) {
|
||||
std::cout << "Enter name and class of student " << i + 1 << ": ";
|
||||
std::string name {};
|
||||
size_t standard {};
|
||||
std::cin >> name >> standard;
|
||||
class1[i] = student {name, standard};
|
||||
}
|
||||
|
||||
// Now, let's tro to access the student out of range in the array
|
||||
try {
|
||||
class1[nStudents] =student{"John", 8}; // No exception, endeffined behaviour
|
||||
std::cout << "class1 student set out of range without exception" << std::endl;
|
||||
class1.at(nStudents) = student{"John", 8}; // Will throw exception
|
||||
}
|
||||
catch(...) {
|
||||
std::cout << "Exception caught" << std::endl;
|
||||
}
|
||||
|
||||
auto class2 = class1; // Deep copy
|
||||
|
||||
std::cout << "Second class after initialized using first array: " << class2.to_string() << std::endl;
|
||||
|
||||
auto class3 = class1 + class2; // Combines both classes and creates a bigger one
|
||||
|
||||
std::cout << "Combined class: ";
|
||||
std::cout << class3.to_string() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
30
cpp/iterator.cpp
Normal file
30
cpp/iterator.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <iostream>
|
||||
#include <forward_list>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
std::vector<std::string> vec { "Lewis Hamilton", "Lewis Hamilton", "Nico Roseberg", "Sebastain Vettel", "Lewis Hamilton", "Sebastain Vettel", "Sebastain Vettel", "Sebastain Vettel", "Fernando Alonso" };
|
||||
|
||||
auto it { vec.begin() }; // Constant time
|
||||
std::cout << "Latest winner is: " << *it << std::endl;
|
||||
|
||||
it += 8; // Constant time
|
||||
std::cout << "Winner before 8 years was: " << *it << std::endl;
|
||||
|
||||
std::advance(it, -3); // Contant time
|
||||
std::cout << "Winner before 3 years of that was: " << *it << std::endl;
|
||||
|
||||
std::forward_list<std::string> fwd { vec.begin(), vec.end() };
|
||||
|
||||
auto it1 { fwd.begin() };
|
||||
std::cout << "Latest winner is: " << *it1 << std::endl;
|
||||
|
||||
std::advance(it1, 5); // Time taken is proportional to the number of elements
|
||||
|
||||
std::cout << "Winner before 5 years was: " << *it1 << std::endl;
|
||||
|
||||
// Going back will result in compilr time error as forward_list only allows us to move towards the end.
|
||||
// std::advance(it1, -2); // Compiler error
|
||||
|
||||
return 0;
|
||||
}
|
111
cpp/singly_ll.cpp
Normal file
111
cpp/singly_ll.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
template <class T>
|
||||
struct singly_ll_node {
|
||||
T data {};
|
||||
singly_ll_node* next {};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class singly_ll {
|
||||
public:
|
||||
using node = singly_ll_node<T>;
|
||||
using node_ptr = node* ;
|
||||
|
||||
private:
|
||||
node_ptr head {};
|
||||
|
||||
public:
|
||||
void push_front(T val) {
|
||||
auto new_node = new node{val, nullptr};
|
||||
if (head != nullptr) new_node -> next = head;
|
||||
head = new_node;
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
auto first { head };
|
||||
if (head) {
|
||||
head = head -> next;
|
||||
delete first;
|
||||
}
|
||||
else throw "Empty ";
|
||||
}
|
||||
|
||||
struct singly_ll_iterator {
|
||||
private:
|
||||
node_ptr ptr;
|
||||
|
||||
public:
|
||||
singly_ll_iterator(node_ptr p) : ptr(p) {}
|
||||
|
||||
T& operator*() {
|
||||
return ptr -> data;
|
||||
}
|
||||
|
||||
node_ptr get() {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
singly_ll_iterator& operator++() { // pre-increment
|
||||
ptr = ptr -> next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
singly_ll_iterator operator++(T) { // post-increment
|
||||
singly_ll_iterator result { *this };
|
||||
++(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator==(const singly_ll_iterator& left, const singly_ll_iterator& right) {
|
||||
return left.ptr == right.ptr;
|
||||
}
|
||||
|
||||
friend bool operator!=(const singly_ll_iterator& left, const singly_ll_iterator& right) {
|
||||
return left.ptr != right.ptr;
|
||||
}
|
||||
};
|
||||
|
||||
singly_ll_iterator begin() {
|
||||
return singly_ll_iterator(head);
|
||||
}
|
||||
|
||||
singly_ll_iterator end() {
|
||||
return singly_ll_iterator(nullptr);
|
||||
}
|
||||
|
||||
singly_ll_iterator begin() const {
|
||||
return singly_ll_iterator(head);
|
||||
}
|
||||
|
||||
singly_ll_iterator end() const {
|
||||
return singly_ll_iterator(nullptr);
|
||||
}
|
||||
|
||||
singly_ll() = default;
|
||||
|
||||
singly_ll(const singly_ll& other) : head(nullptr) {
|
||||
if (other.head) {
|
||||
head = new node;
|
||||
auto cur {head};
|
||||
auto it {other.begin()};
|
||||
while (true) {
|
||||
cur -> data = *it;
|
||||
|
||||
auto tmp {it};
|
||||
++tmp;
|
||||
if (tmp == other.end()) break;
|
||||
|
||||
cur -> next = new node;
|
||||
cur = cur -> next;
|
||||
it = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
singly_ll(const std::initializer_list<T>& ilist) : head(nullptr) {
|
||||
for (auto it {std::rbegin(ilist)}; it != std::rend(ilist); ++it) push_front(*it);
|
||||
}
|
||||
};
|
||||
|
43
cpp/voting.cpp
Normal file
43
cpp/voting.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <iostream>
|
||||
#include <forward_list>
|
||||
|
||||
struct citizen {
|
||||
std::string name {};
|
||||
size_t age {};
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const citizen& c) {
|
||||
return (os << "[Name: " << c.name << ", Age: " << c.age << "]");
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::forward_list<citizen> citizens { {"Raj", 22}, {"Rohit", 25}, {"Rohan", 17}, {"Sachin", 16} };
|
||||
|
||||
auto citizens_copy { citizens };
|
||||
|
||||
std::cout << "All the citizens: ";
|
||||
for (const auto& c : citizens) std::cout << c << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
citizens.remove_if(
|
||||
[](const citizen& c) {
|
||||
return (c.age < 18);
|
||||
});
|
||||
|
||||
std::cout << "Eligible citizens for voting: ";
|
||||
for (const auto& c : citizens) std::cout << c << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
citizens_copy.remove_if(
|
||||
[](const citizen& c) {
|
||||
// Returns true if age is less than 18
|
||||
return (c.age != 17);
|
||||
}
|
||||
);
|
||||
|
||||
std::cout << "Citizens that will be eligible for voting next year: ";
|
||||
for (const auto& c : citizens_copy) std::cout << c << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue