I am trying to implement a vector using my own class so I can not do the initialiser list part
# include <iostream>
# include <exception>
# include<initializer_list>
template <class T>
class vector {
public:
T* a;
T n;
int pos, c;
vector() { a = 0; n = 0; }
vector(T n) : n(n) { a = new T[n]; }
vector(std::initializer_list <vector> l) {
a = new T[int(sizeof(l))];
for (int f : l)
*(a + f) = l.begin() + f;
}
void push_back(T k) {
int i = k;
*(a + n) = k;
}
vector& operator= (vector&& th) {
this->a = th.a;
th.a = nullptr; return (*this);
}
vector& operator=(vector& k)
{
this->a = k.a;
return(*this);
}
int size() { return n; }
void pop_back() { *(a + n) = nullptr;
n--;
}
void resize(int c) {
delete a;
n = c;
a = new T[c];
}
T operator[](int pos) {
if (pos > sizeof(a))
std::cout << "out of range";
else return *(a + pos);
}
};
int main() {
vector<int> a(10);
vector<char>b{ 'w','b','f','g' };
getchar();
return 0;
}
I am just trying to use pointer offset notation to take the initializer list items into the dynamic array but I get errors VS 17 IDE
Severity Code Description Project File Line Suppression
Error C2440 '=': cannot convert from 'const _Elem *' to 'T'
Error C2440 'initializing': cannot convert from 'const _Elem' to 'int'
Hello Nimrod!
#include <iostream>
#include <exception>
#include <initializer_list>
// normally people don't place a space between '#' and 'include'
template <class T>
class vector {
public:
T* a;
int n;
// probably it is length the vector
// change T to int
int pos, c;
vector() {
a = nullptr;
// do not use '0' to instruct null pointer
n = 0;
}
vector(int n): n(n) { a = new T[n]; }
vector(std::initializer_list<T> l) {
a = new T[l.size()];
// redundant force cast from size_t to int
for (int i = 0; i < l.size(); i++) {
a[i] = l.begin()[i];
}
// for (int f : l) # it seems that you wrote JavaScript before?
// *(a + f) = l.begin() + f;
}
void push_back(T k) {
// assigns "T k" to "int i"? it's confusing
// int i = k;
// *(a + n) = k;
}
// probably still many problems
vector& operator=(vector&& th) {
this->a = th.a;
th.a = nullptr;
return (*this);
}
vector& operator=(vector& k) {
this->a = k.a;
return(*this);
}
int size() { return n; }
void pop_back() { *(a + n) = nullptr;
n--;
}
void resize(int c) {
delete a;
n = c;
a = new T[c];
}
T operator[](int pos) {
if (pos > sizeof(a))
std::cout << "out of range";
else return *(a + pos);
}
};
int main() {
vector<int> a(10);
vector<char>b{ 'w','b','f','g' };
getchar();
return 0;
}
You still need more practice. XP
In your context of code, template variable for initializer_list should be T rather than int.
Range for loop with initializer_list<T> will fetch the values
in the list. Therefore it should belong to T.
Related
I need to overload the + operation like this a + b = max(a,b).
And accordingly I need it to work for matrix addition and matrix multiplication and some other operations (trace, power,etc.). Here \bigoplus is max operation
What's the best way to do this with Eigen? I read about eigen extension here, but I don't understand how to do that for my task.
Currently I have this:
#include <iostream>
#include <Eigen/Dense>
#include <algorithm>
using namespace Eigen;
namespace MaxAlgebra {
template <typename T>
T operator+(const T& a,const T& b) {
T c(a.rows(),a.cols());
for (uint i = 0; i < a.rows(); ++i) {
for (uint j = 0; j < a.cols(); ++j) {
c(i,j) = std::max(a(i,j),b(i,j));
}
}
return c;
}
template <typename T>
T operator*(const T& a,const T& b){
T c(a.rows(),b.cols());
for (uint i = 0; i < a.rows(); ++i) {
for (uint j = 0; j < b.cols(); ++j) {
std::vector<uint> values;
for (uint k = 0; k < a.cols(); ++k) {
values.push_back(a(i,k) * b(k,j));
}
c(i,j) = *std::max_element(begin(values),end(values));
}
}
return c;
}
template <typename T>
uint trace(const T& a) {
std::vector<uint> values;
for (uint i = 0; i < a.rows(); ++i) {
values.push_back(a(i,i));
}
return *std::max_element(begin(values),end(values));
}
}
int main() {
MatrixXd x(2,2);
MatrixXd y(2,2);
x(0,0) = 3;
x(1,0) = 2;
x(0,1) = 1;
x(1,1) = 2;
y(0,0) = 2;
y(1,0) = 1;
y(0,1) = 2;
y(1,1) = 3;
MatrixXd c = MaxAlgebra::operator*(x,y);
std::cout << "Here is the matrix a:\n" << x << std::endl;
std::cout << "Here is the matrix b:\n" << y << std::endl;
std::cout << "Here is the matrix c:\n" << c << std::endl;
return 0;
}
If I understand your algebra correctly, you could simply create a custom scalar type. This seems to work:
template<class T>
struct MaxAlg
{
T scalar;
MaxAlg() = default;
MaxAlg(T scalar) noexcept // implicit conversion for convenience
: scalar(scalar)
{}
explicit operator T() const noexcept
{ return scalar; }
MaxAlg& operator+=(MaxAlg o) noexcept
{
scalar = std::max(scalar, o.scalar);
return *this;
}
friend MaxAlg operator+(MaxAlg left, MaxAlg right) noexcept
{ left += right; return left; }
MaxAlg& operator*=(MaxAlg o) noexcept
{
scalar *= o.scalar;
return *this;
}
friend MaxAlg operator*(MaxAlg left, MaxAlg right) noexcept
{ left *= right; return left; }
friend bool operator==(MaxAlg left, MaxAlg right) noexcept
{ return left.scalar == right.scalar; }
friend bool operator!=(MaxAlg left, MaxAlg right) noexcept
{ return left.scalar != right.scalar; }
friend bool operator<(MaxAlg left, MaxAlg right) noexcept
{ return left.scalar < right.scalar; }
friend bool operator<=(MaxAlg left, MaxAlg right) noexcept
{ return left.scalar <= right.scalar; }
friend bool operator>(MaxAlg left, MaxAlg right) noexcept
{ return left.scalar > right.scalar; }
friend bool operator>=(MaxAlg left, MaxAlg right) noexcept
{ return left.scalar >= right.scalar; }
friend std::ostream& operator<<(std::ostream& left, MaxAlg right)
{ return left << right.scalar; }
};
template<class T, Eigen::Index Rows, Eigen::Index Cols>
using MaxAlgMatrix = Eigen::Matrix<MaxAlg<T>, Rows, Cols>;
template<class T, Eigen::Index Rows, Eigen::Index Cols>
using MaxAlgArray = Eigen::Array<MaxAlg<T>, Rows, Cols>;
using MaxAlgMatrixXd = MaxAlgMatrix<double, Eigen::Dynamic, Eigen::Dynamic>;
using MaxAlgVectorXd = MaxAlgMatrix<double, Eigen::Dynamic, 1>;
using MaxAlgArrayXXd = MaxAlgArray<double, Eigen::Dynamic, Eigen::Dynamic>;
using MaxAlgArrayXd = MaxAlgArray<double, Eigen::Dynamic, 1>;
int main()
{
Eigen::MatrixXd a = Eigen::MatrixXd::Random(10, 10);
Eigen::MatrixXd b = Eigen::MatrixXd::Random(10, 10);
MaxAlgMatrixXd maxalg_a = a.cast<MaxAlg<double> >();
MaxAlgMatrixXd maxalg_b = b.cast<MaxAlg<double> >();
std::cout << (maxalg_a * maxalg_b).cast<double>() << "\n\n";
std::cout << (maxalg_a.array() + maxalg_b.array()).cast<double>() << "\n\n";
std::cout << a.cwiseMax(b) << "\n\n";
}
This disables Eigen's vectorization but the compiler can still do it when you compile with -O3 and it is a lot less work.
I need to start execution of vector of tasks in parallel and wait until finished. Here is how I did this, but I get future_error on MSVC. Small utility to split vector into parts:
template<typename T>
vector<vector<T>> split(const vector<T>& vec, size_t n) {
vector<vector<T>> outVec;
size_t length = vec.size() / n;
size_t remain = vec.size() % n;
size_t begin = 0;
size_t end = 0;
for (size_t i = 0; i < std::min(n, vec.size()); ++i) {
end += (remain > 0) ? (length + !!(remain--)) : length;
outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end));
begin = end;
}
return outVec;
};
launch async execution:
template <typename T, typename R, typename F>
void execInParallel(vector<T> &tasks, vector<R> &res, F&&f, int cores) {
function<int(int &t)> fn(std::forward<F>(f));
auto parts = split(tasks, cores);
vector<future<vector<R>>*> threads;
for (auto part: parts) {
future<vector<R>> thrd=async(launch::async, [&](vector<T> tasks) {
vector<R> rs;
for (auto&t : tasks) {
rs.push_back(fn(t));
}
return rs;
}, part);
threads.push_back(&thrd);
}
for (auto&thrd : threads) {
vector<R> rs = thrd->get();
for (auto &r : rs)
res.push_back(r);
}
};
test on stupid example:
int main(){
vector<int> tasks,res;
tasks.push_back(1);
tasks.push_back(7);
tasks.push_back(19);
execInParallel(tasks,res, [&](int&t) {
return t+8;
}, 2);
return 0;
}
May be I am inventing a bicycle? Is there anything like that in C++11 or boost out of the box? Any example available?
Custom lambda Comparator slower than normal function c++11. I experienced this a few times. But, Still Couldn't figure out the reason why this is so. Does anyone experience this and know the cause behind it?
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 1;
vector<int> v(N);
vector<int> sorted(N);
map<int, int> counts;
long long start;
void startClock() {
start = clock();
}
void stopClock() {
cout << float( clock () - start ) / CLOCKS_PER_SEC << endl;
}
void copyOriginal() {
for (int i = 0; i < N; ++i)
sorted[i] = v[i];
}
void sortWLambda(map<int, int>& counts) {
cout << "sorting with lambda" << endl;
sort(sorted.begin(), sorted.end(), [counts](const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
});
}
bool comparator(const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
}
void sortWoLambda() {
cout << "sorting w/o lambda" << endl;
sort(sorted.begin(), sorted.end(), comparator);
}
int main() {
for (int i = 0; i < N; ++i) {
int num = rand() % 1234;
counts[num]++;
v[i] = num;
}
copyOriginal();
startClock();
sortWLambda(counts);
stopClock();
copyOriginal();
startClock();
sortWoLambda();
stopClock();
return 0;
}
sorting with lambda 6.28 sec
sorting w/o lambda 0.17 sec
pass by reference made the difference for lambda.
I tried this..
sort(sorted.begin(), sorted.end(), [&counts](const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
});
now this takes same time as normal function
Passing by constant reference in the lambda capture list this helped me too!
#ifndef HASHMAP_H
#define HASHMAP_H
#include <iostream>
#include <string>
#include <vector>
using namespace std;
enum Status{open , active, deactivated };
//template <typename T>
template</*typename Key,*/ typename T>
class hashmap{
private:
class Node{
public:
const string Key;
//vector<T> values;
T value;
Status status;
Node(string key, T val) :Key(key), value(val), status(active){}
void operator =(const Node &n){
string *ptr;
ptr = (string*)(&(this->Key));
*ptr = n.Key;
//Node(n);
this->status = n.status;
this->value = n.value;
}
Node() :status(open){}
Node(const string& key) :Key(key), status(active){}
//Node(const Node &n) : value(n.val), status(n.status){}
};
//typedef map<
unsigned int hash(const string& s, int tableSize){
unsigned int h = 0;
/*each(s)*/
for(auto it : s) h = 31 * h + unsigned(it);
return h % tableSize;
}
unsigned int hash(const string& s){
return hash(s, table_size);
}
int table_size = 103;
vector<Node> table;
typedef typename vector<Node>::iterator iter;
public:
//default constructor
hashmap(){
table = vector<Node>(table_size);
}
//copy constructor
hashmap(const hashmap& x){
table = x.table;
//for (auto it = )
}
//assignment operator //has been removed
hashmap& operator=(const hashmap& x){
this->table.erase(this->table.begin(), this->table.begin() + 103);
for ( int i = 0; i < x.table_size; i++){
this->table.push_back(x.table.at(i));
}
return *this;
}
//destructor
~hashmap(){
table.clear();
}
//index operator
T& operator[](const string x){
int h = hash(x, table.size());
if (table[h].Key == x){
return (table[h].value);
}
else {
Node* n = new Node(x);
table[h] = *n;
return (table[h].value);
}
}
//Node test
void okay(const string x,int i){
Node *temp = new Node(x, i);
cout << temp->status << endl;
/*cout << table[1].status << endl;
cout << table[2].status << endl;
table.at(0) = (*temp);
cout << table[0].Key << endl;
cout << table[0].value << endl;
cout << table[3].status << endl;*/
}
int stride(int x){
return (7-x%7);
}
//find()
iter find(const string& x){
int h = hash(x);
int s = stride(h);
int t = table_size;
int z;
//for (int i = 0; i < t; i++){
for (int i = hash(x, table_size) % t; i != t; i = (i + stride(h)) % t){
z = (h + i*s) % table_size;
if (table[z].status == open) return NULL;
if (table[z].status == deactivated) continue;
if (table[z].Key == x) return &table[h];
}
return table.end();
}
//begin()
iter begin(){
return table.begin();
}
//end()
iter end(){
return table.end();
}
};
#endif // !HASHMAP_H
Everything seems to be working fine except the find function. It's suppose to probe through the vector and return values upon conditions but the problem I'm having is I get these errors about return type conflicts.
Error2error C2664: 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap::Node>>>::_Vector_iterator(const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap::Node>>> &)' : cannot convert argument 1 from 'hashmap<int>::Node *' to 'const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>> &'
Error1error C2664: 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>>::_Vector_iterator(const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>> &)' : cannot convert argument 1 from 'int' to 'const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>> &'
How can I edit the iterator to fix this?
thank you.
Trying to Sort and Merge two Vectors
keep getting this error:
c:\users\austin\documents\visual studio 2013\projects\hw 16\hw 16\h16.cpp(42): error C3861: 'lowestVal': identifier not found
How could i improve my code
vector mergeSorted(const vector& a, const vector& b)
{
vector result;
int m = 0;
if (a.size() < b.size())
{
m = a.size();
}
else
{
m = b.size();
}
for (int i = 0; i < m; i++)
{
result.push_back(a[i]);
result.push_back(b[i]);
}
if (m == a.size())
{
result.insert(result.end(), b.begin() + m, b.end());
}
if (m == b.size())
{
result.insert(result.end(), a.begin() + m, a.end());
}
for (size_t i = 0; i < result.size(); i++)
{
//function that checks for lowest val
result.insert(result.begin() + lowestVal(result, a[i]), a[i]);
}
return result;
}
int lowestVal(const vector& v, int val)
{
for (size_t i = 0; i < v.size(); i++)
{
if (val < v[i])
{
return i;
}
else
{
return v.size();
}
}
}
Put the declaration of lowestVal before it is called:
int lowestVal(const vector& v, int val);
vector mergeSorted(const vector& a, const vector& b) { // ...
This is called forward declaration. Compiler must know the type of the identifier, so it must be declared before using.