add cpp array and list

This commit is contained in:
Aditya 2022-09-17 10:04:05 +05:30
parent a5f0cb8f4c
commit e326c0cd1a
6 changed files with 447 additions and 0 deletions

17
cpp/build_array.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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;
}