I want to store queues in a queue structure from the stl library. For some reasons I have to store a queue in each iteration of my program, but I think that create a new queue over and over again is too expensive.
I only know two ways to do this. The first one:
#include <iostream>
#include <deque>
using namespace std;
int main () {
unsigned int limit, i = 0;
deque<deque<int> > container;
cin >> limit;
for ( ; i < limit; i++ ) {
deque<int> values;
//set some values in the values structure.
setValues(values, i);
container.push(values);
}
}
the second one:
#include <iostream>
#include <deque>
using namespace std;
int main () {
unsigned int limit, i = 0;
deque<deque<int> > container;
deque<int> values;
cin >> limit;
for ( ; i < limit; i++ ) {
//reset the structure, i.e. delete al the previous values.
reset(values);
//set some values in the values structure.
setValues(values, i);
container.push(values);
}
}
the problem here is that I don't know any function for reset my queue, or maybe I have to do values=NULL?
How can I do this in an efficient way?
Thanks! :D
You can push an empty deque in the loop, get a reference to it, and then add items to it.
#include <iostream>
#include <deque>
using namespace std;
int main () {
unsigned int limit, i = 0;
deque<deque<int> > container;
cin >> limit;
for ( ; i < limit; i++ ) {
container.push_back(deque<int>());
deque<int>& values = container.back();
//set some values in the values structure.
setValues(values, i); }
}
You should check in debugger what your compiler is actually doing when you make copies of deque. I have checked in VS2013 and its all move semantics - as expected. This is a test code:
std::deque<int> getValues() {
std::deque<int> res;
res.push_back(1);
return res; // deque(_Myt&& _Right) called, also other compilers might use RVO
}
std::deque<int> ff;
std::deque<std::deque<int>> aff;
aff.push_back(getValues()); // void push_back(value_type&& _Val) called
at first it looks like a lot of copying, but actually in both problematic places move semantics are used, and only pointers of temporary objects are copied, so its all super fast.
But maybe you are stuct in pre c++11 world? At least this fragment
deque<deque<int> > container;
^^^
gives such a hint.
Related
Here I'm trying to mimic data feed streaming from stock exchange using random number and subsequently store it in array.
#include <iostream>
#include <array>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <chrono>
#include <ctime>
#include <stdlib.h>
long int prevcntr=0;
using namespace std;
std::pair<long int, double>feedgenerator(long int len)
{
srand(time(0));
for(long int itr=1;itr<=len;itr++)
{
return {itr, (double)rand()/RAND_MAX};
//should continue evaluating the function without exiting
pause(0.001); //To allow some interval for 'makearray' to store it
}
}
template<size_t nn>
std::array<double, nn> makearray(long int cntr, double value, long int len)
{
std::array<double, nn> outarr; // should be able to pass the value of 'len' to 'nn'
long int itr=0;
begin:
while(cntr <= prevcntr)goto begin; // should wait until the next update
outarr[itr] = value;
prevcntr = cntr;
while(itr<len)
{
itr++;
goto begin; // control goes back to the beginning until all the elements of the array are filled with value
}
//should return the array after it is fully filled
return outarr;
}
int main()
{
double *p=new double[];
long int len = 100000;
*p = makearray(feedgenerator(len), len)
// I should be able to call these as nested functions as above
for(int i=0;i<len;i++)
cout<<*p[i]<<"\n";
return 0;
}
Question is how do I return a value without exiting the feedgenerator function. If I try to get all the values at once then it wouldn't mimic the data feed. Data feed is essentially, the same value being updated, sequentially.
To store the data, makearray is being used (vector shouldn't be used as it is extremely slow).
Overall the idea is, feedgenerator should update the same value with an increasing counter (in the real scenario counter will be the time and value will be price etc.) and makearray should store the data (Unless I store the data, the data would be lost, as in the case of data feed from stock exchange) for subsequent analysis.
In makearray, I want to pass the length of the array as an argument of the function, so that it can be controlled by another program. How can it be done is not clear to me.
The code in it's present form, doesn't compile.
Question is how do I return a value without exiting the feedgenerator function
Because you are trying to mimic the data feed stream from stock exchange, so, I think you should consider to use thread. Example:
#include <unistd.h>
#include <deque>
#include <vector>
#include <algorithm>
#include <mutex>
#include <thread>
#include <iostream>
class FeedGenerator {
long int max_length;
std::deque<double> queue;
std::mutex mutex;
std::thread thread;
bool stop;
public:
FeedGenerator(long int len) :
max_length(len), stop(false),
thread(&FeedGenerator::run, this) {
}
virtual ~FeedGenerator() {
stop = true;
thread.join();
}
// Get the latest `len` values
int getData(std::vector<double>& vec, int len) {
std::lock_guard<std::mutex> lock(mutex);
if (queue.empty()) return 0;
int nlen = std::min((size_t)len, queue.size());
vec.resize(nlen);
std::copy(queue.end() - nlen, queue.end(), vec.begin());
return nlen;
}
private:
void run() {
srand(time(0));
while (!stop)
{
{
std::lock_guard<std::mutex> lock(mutex);
queue.push_back((double)rand()/RAND_MAX);
if (queue.size() >= max_length) {
queue.pop_front();
}
}
usleep(1000);
}
}
};
int main()
{
long int len = 100000;
FeedGenerator feedgenerator(len);
sleep(1);
std::vector<double> p;
feedgenerator.getData(p, 10); // get the latest 10 values
for(int i=0;i<p.size();i++)
std::cout << p[i] << std::endl;
return 0;
}
I try to implement graph bfs but get compiler error
error:
invalid types '<unresolved overloaded function type>[int]' for array subscript|
My questions:
Is my approach making array of vector of struct is right approach? And how can I solve the compiler error?
How to initialize array value to infinity?
When making undirected graph, should I push back 2 times?
My code:
#include <iostream>
#include <deque>
#include <vector>
#define INT_MAX 21422
using namespace std;
int distancee[10]={4,4,4,4,4,4,4,4,4,4}; //want to intialize all to infinity
struct bfss{
int firstt;
int secondd;
};
vector<bfss>bfs[10];
void bfsfunc(int start){
deque<int> q;
q.push_back(start);
distancee[start]=0;
while(!q.empty()){
int v=q.front();
q.pop_front();
for(int i=0;i<bfs[v].size();i++){
if(distance[bfs[v][i].firstt]>(distance[v]+bfs[v][i].secondd)){ // got error in this line
distance[bfs[v][i].firstt]=distance[v]+bfs[v][i].secondd;
if(bfs[v][i].second==0)
{
q.push_front(bfs[v][i].first);
} else {
q.push_back(bfs[v][i].second);
}
}
}
}
}
int main()
{
int edges,nodes,x,y,z;
cin>>edges>>nodes;
for(int i=0;i<edges;i++){
cin>>x>>y>>z; //x is array subscript , y is node(x-y is edge) , z is weight
bfss newbfs;
newbfs.firstt=y;
newbfs.secondd=z;
bfs[x].push_back(newbfs);
bfss newbfs;
newbfs.firstt=x;
newbfs.secondd=z;
bfs[y].push_back(newbfs); // when making undirected graph, should i push back 2 times?
}
bfsfunc(0);
return 0;
}
As mentioned, you had a few typos on distancee, firstt and secondd. Fix those and the errors goes away. For an int the closest you'll come to infinity is it's max value. With that and a few other minor changes (comments in the code), this is what I came up with:
#include <iostream>
#include <deque>
#include <vector>
#include <array>
#include <limits> // std::numeric_limits
// removed using namespace std;
// max distance: not infinity, but hopefully large enough
constexpr int md = std::numeric_limits<int>::max();
// replaced the C array with a standard C++ array
std::array<int, 10> distancee={md,md,md,md,md,md,md,md,md,md};
struct bfss { // shouldn't these be unsigned?
int firstt;
int secondd;
};
std::vector<std::vector<bfss>> bfs(10); // replaced C array with a standard C++ vector
void bfsfunc(int start) {
std::deque<int> q;
q.push_back(start);
distancee[start]=0;
while(!q.empty()) {
int v=q.front();
q.pop_front();
// using size_t intstead of int for array subscript
for(size_t i=0;i<bfs[v].size();i++) {
if(distancee[bfs[v][i].firstt]>(distancee[v]+bfs[v][i].secondd)) {
distancee[bfs[v][i].firstt]=distancee[v]+bfs[v][i].secondd;
if(bfs[v][i].secondd==0) {
q.push_front(bfs[v][i].firstt);
} else {
q.push_back(bfs[v][i].secondd);
}
}
}
}
}
int main()
{
int edges,nodes,x,y,z;
std::cin>>edges>>nodes;
for(int i=0;i<edges;i++) {
std::cin>>x>>y>>z; //x is array subscript , y is node(x-y is edge) , z is weight
// using emplace_back to let the vector create the bfss in place
bfs[x].emplace_back(bfss{y, z});
bfs[y].emplace_back(bfss{x, z});
}
bfsfunc(0);
return 0;
}
I don't know the answer to the question about pushing twice since I don't know the algorithm.
I'm trying to learn memoization in C++ and have implemented two Fibonacci functions using map and vector. I've submitted them to the Coursera data structures course. The vector implementation fails due to taking too much time and the map passes OK. As both implement memoization could anybody suggest why one fails and the other passes?
#include <iostream>
#include <map>
#include <iterator>
#include <vector>
using namespace std;
int fibonacci_fast_vector(int n)
{
vector <int> cache;
if(n<=1) {
return n;
}
else if ((unsigned)n >= cache.size()) {
cache.resize(n+1);
}
if(cache[n] != 0) {
return cache[n];
}
// otherwise
int ret=fibonacci_fast_vector(n-1)+fibonacci_fast_vector(n-2);
cache[n]=ret;
return ret;
}
int fibonacci_fast_map(int n)
{
static map<int,int>memo;
if(n<=1)
return n;
if(memo.count(n)>0) { /*if it is in the map return the element*/
return memo[n];
}
// otherwise
int ret=fibonacci_fast_map(n-1)+fibonacci_fast_map(n-2);
memo[n]=ret;
return ret;
}
int main() {
int n = 0;
std::cin >> n;
std::cout << fibonacci_fast_map(n) << '\n';
std::cout << fibonacci_fast_vector(n) << '\n';
return 0;
}
In this code:
int fibonacci_fast_vector(int n)
{
vector <int> cache;
your vector is not static so you create a new vector on every function call, so your "memoization" not only fails to work but actually makes it slower.
Btw this code:
if(memo.count(n)>0) { /*if it is in the map return the element*/
return memo[n];
}
is unnecessary inefficient - you are doing 2 lookups in case data is there or 2 lookups if it is not, which is significantly expensive operation on a map. You should use something like this:
auto p = memo.emplace(n,0);
if( p.second ) // data was not there
p.first->second = fibonacci_fast_map(n-1)+fibonacci_fast_map(n-2);
return p.first->second;
I guess the problem is that your vector is not static. Put a static keyword or declare it in the global scope. This will reduce the huge performance time because you avoid many news and deletes. Also you can create with some initial size vector if you know the probable size for the same performance reason.
I am creating my first C++ program with GUI.
I am using Code::Blocks v16.01 and wxWidgets v3.03.
I have found that in the wxComboBox class constructor, the type that stands for choices is wxArrayString. I have tried to convert vector to vector and later to vector and to wxArrayString, but it failed miserably...
My question is how to set default choice values of wxComboBox object?
Preferably I would like them to be filled with values of vector, created during program execution.
Here is the code:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
vector <double> vector_double;
vector <string> vector_string;
vector <wxString> vector_wxstring;
void convert_double_to_string(vector<double> &dbl, vector <string> &str)
{
for (int i = 0; i < dbl.size(); i++)
{
ostringstream stream;
stream << dbl[i];
str.push_back(stream.str());
}
}
void convert_string_to_wxString(vector<string> & str, vector <wxString> &wxstr);
{
for (int i = 0; i < str.size(); i++)
{
wxstr.push_back(_(str[i]));
}
}
void main()
{
/////////
// here setting vector_double's values
//////////
convert_double_to_string(vector_double, vector_string);
convert_string_to_wxString(vector<string> vector_string, vector_wxstring);
}
This is what I have got. The string conversion to wxString is not working though. And even if it would, I wouldn't know how to insert it into wxArrayString.
Something along these lines:
wxComboBox * cbo = new wxComboBox( ... );
wxArrayString as;
for ( auto& s : vector_string )
as.Add( s );
cbo->Set( as );
#include <vector>
#include <iostream>
using namespace std;
void SubSetNum(bool * select, int*a, int selectk, int k, int selectn, int n )// depthk to
{
if(k>n) return;
if(selectn==n)
{
if(selectk==k)
{
for(int i=0;i<n;i++)
if(select[i]==true)
cout<<a[i];
cout<<endl;
}
return;
}
select[selectk]=false;
SubSetNum(select,a,selectk,k,selectn+1,n);
select[selectk]=true;
SubSetNum(select,a,selectk+1,k,selectn+1,n);
}
int main()
{
int k=3;
int n=5;
int a[]={1,5,8,10,13};
//while(cin>>k)
{
bool *select=new bool[n];
memset(select,0,sizeof(bool)*n);
SubSetNum(select,a,0,k,0,n);
delete []select;
}
return 0;
}
This a question, that I want to get k elements from n elements set.
But it prints out incorrect answer? I am always confused when I design recursive algorithms...Especially the parameter of functions, if or not return value, and so on, thus I always try to forcely remember the code in textbook.
Your mistake is here:
select[selectk]=false;
...
select[selectk]=true;
It should be this:
select[selectn]=false;
...
select[selectn]=true;
I believe the cause of the mistake was a failure to remember what the variables represent. The variable selectn is the index of the element being included or excluded. The variable selectk is the number of elements already included. It does not make sense to use selectk as an index into a.