C++ swap() for deque indexes - c++

I have two questions, the second being optional.
First, in the program below (a prototype of a simple card program), I am getting the following error:
(29): error C2660: 'shuffle' : function does not take 1 arguments
with the following code:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <deque>
#include <algorithm>
using namespace std;
deque<int> cardDeck (51);
void flip(); //Prototype flip()
void shuffle(); //Prototype shuffle()
int _tmain(int argc, _TCHAR* argv[])
{
ostream& operator<<(ostream& os, deque<int> dq); //overload << operator to accept deque
//arguments
for (int a=52; a>0; a--) { //initialize the 52 cards in a deck
cardDeck.push_front(a);
}
flip(); //prompt my input to check data
return 0;
}
void flip() { //flip over card in specified location in the deck
int input;
cin >> input;
cout<<cardDeck[input]<<endl;
shuffle(cardDeck);
flip();
}
void shuffle(deque<int> dq) { //use Fisher-Yates algorithm to efficiently and accurately
//randomize card order
for(int i=dq.size()-1; i>-1; i--) {
int j = rand() % (i + 1);
if(i != j) {
swap(dq[j], dq[i]);
}
}
}
Why do I receive this error? (I have looked around and attempted to solve it myself)
Secondly, I'm not certain if I'm doing the fisher-yates algorithm properly because c++ documentation isn't easy to find on it (for the version that utilizes swap();) (Brownie points for answering this or pointing out any horribly awful coding practices, not including the lack of classes)
Thanks in advance!

The reason you get that error is because you declare shuffle as a function not taking any arguments.
void shuffle();
Another note is that you probably want to take a reference to the deque in that function, otherwise you'll shuffle a local copy and won't have the desired side effect.
You probably want it to lok like this:
void shuffle(deque<int>& dq);
Also, you might want to use iter_swap instead of swap to swap the elements. In a dequeue it probably won't make a difference, but for list or map it would.

I think you forgot to put the argument in your function declaration
void shuffle();
should be
void shuffle(deque<int> dq);

I think that the problem is that at the top of your program you've prototyped `shuffle as
void shuffle();
Notice that this takes no arguments. Because C++ uses a one-pass compiler, at the point that you call shuffle, this is the only declaration of shuffle available because the compiler hasn't seen the implementation later on. Consequently, it gives you the above error, because it thinks you are calling a zero-argument function with one argument.
To fix this, update the prototype so that it matches the function you've actually defined.
Hope this helps!

Related

Output parameters with arrays in one function with Arduino and C ++

I have a problem with the initialization with various parameters in my function.
It works if I have created an array int params [] = {...}. However, it doesn't work if I want to write the parameters directly into the function.
declaration (in the .h)
void phase_an(int led[]);
in the .cpp
void RS_Schaltung::phase_an(int led[])
{
for (size_t i = 0; i < LEN(led); i++) {
digitalWrite(led[i], HIGH);
}
}
if I try this way, it won't work. I would like it to be like that. But I couldn't find anything about it on the internet. ...:
in the Arduino sketch:
RS.phase_an(RS.ampelRot, RS.ampelGelb, ..... ); <--- is there a way to do it like that?
what amazes me is that it works this way:
int p_an [5] = {RS.ampelRot, RS.ampelGelb, RS.ampelGruen, RS.rot, RS.gelb};
...................
RS.phase_an (p_an);
does anyone have a suggestion?
There are several ways of making a function accepting a variable number of arguments here.
However, in your current code there is a problem: when you pass a native array of unknown size as argument of a function (e.g. void f(int a[])), the argument will be managed a pointer to an array, and there is no way inside this function to know the real length of that array. I don't know how LEN() is defined, but chances are high that it doesn't works well in your code.
A safer and more practical alternative is to use a vector<int> instead:
#include <iostream>
#include <vector>
using namespace std;
void f(const vector<int>& a){
for (int i=0; i<a.size(); i++) {
cout<<a[i]<<" ";
}
cout<<endl;
}
int main() {
vector<int> test={1,2,3,4};
f(test);
f({1,2,3,4});
return 0;
}
In this case, you can pass your multiple values between bracket in the function call (e.g. ({RS.ampelRot, RS.ampelGelb, RS.ampelGruen, RS.rot, RS.gelb})and C++ will automatically convert it to a vector.

Can I use `distance` as my class member variable name?

It would be ok to define a class like this (ignore its implmentation):
class MyEngine {
private:
int* params;
int param_len;
public:
void set_params(int* _params, int _len);
float get_result(); // relies on `distance` member
float distance; // people can modify this
};
However, if using vector, assume it implicitly includes <iterator> which contains std::distance, how do compiler distinguish std::distance and distance member? (Or will it cause un-expected crash when run?). Say, the function get_result() relies distance member value.
#include <vector>
using namespace std;
class MyEngine {
private:
vector<int> params;
public:
void set_params(int* _params, int _len);
float get_result(); // relies on `distance` member
float distance; // people can modify this
};
update
As people mentioned, using namespace std is bad practice; however, there are still people writing code with using namespace std, and if we are collaborate with them, using their code, is there any concreate example that demonstrate the badness of using namespace std, expecially severe run error? This, would be my real purpose.
There is an answer, saying distinguish the two distance by type. Let's just try this snippet:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iterator>
using namespace std;
class MyEngine {
private:
vector<int> params;
float* distance; // people can modify this
int len;
public:
void setup();
};
void MyEngine::setup()
{
len = 100;
distance = (float*)malloc(sizeof(float)*len);
for(int i=0; i<len; i++) {
distance[0] = len - i;
params.push_back(len-i);
}
int num = distance(params.begin(), params.end());
printf("distance is: %d\n", num);
}
int main(){
MyEngine engine;
int len = 10;
engine.setup();
return 0;
}
Which, would cause compile error saying:
main.cpp:25:23: error: called object type 'float *' is not a function or function pointer
int num = distance(params.begin(), params.end());
~~~~~~~~^
1 error generated.
Demonstrates that it can't distinguish the two distance from their types.
Well, one is MyEngine::distance, and the other is std::distance. They're different names. This is the whole point of scopes.
There is only a problem if you use the unqualified name distance and leave the compiler to figure it out, but if that's not going to work then it'll be because the type of the one chosen doesn't match your usage, so your program won't compile.
If you ever did put things in std then the name can clash in potentially undiagnosable ways, which can cause crashes, and has undefined behaviour per the standard.
The function distance has a different type than the member distance, so the compiler figures that out by the type.
You can even have a function distance(...). As long as parameters are different, they have different type and the compiler figures that out.
Also note that you should not use using namespace std because that also irritates the human reader.
In your updated example, the compiler is indeed confused. You can specify that you want to use the distance function in this case by changing it to int num = std::distance(...);

Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred

#include<iostream>
#include <list>
using namespace std;
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas[];
public:
void print() { cout << *pinakas[0]; return; }
Euler(int korifess, int akmess);
~Euler() { delete[] *pinakas; }
void addAkmes(int kor1, int kor2);
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess) {
*pinakas = new int(korifes);
*pinakas[0] = 89;
}
int main() {
Euler e(2, 1);
e.print();
}
Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred...i can not find where i am wrong in my code.
There are a number of errors in your code, all related to the nature of the pinakas member variable. As it stands, you are declaring this as an array of pointers (to int), and, furthermore, you are using a non-standard syntax for 'flexible' arrays (the empty []).
I don't normally just paste 'fixed' code as an answer but, in this case, that code (with the added \\\ comments where I've made changes) is likely to be the most succinct way to help you.
Although, as many here will no doubt point out, it is far better to avoid the use of 'raw' pointers and the new and delete operators, and use the std::vector container, instead.
#include <iostream>
#include <list>
//using namespace std;/// This is considered 'bad practice' by many programmers
using std::cout;/// Just use the aspect of the STL that you need!
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas;/// This will point an 'array' of integers
public:
void print() {
cout << pinakas[0]; return;/// No longer any need for the dereference (*)
}
Euler(int korifess, int akmess);
~Euler() {
delete[] pinakas;/// No need for the dereference (*)
}
// void addAkmes(int kor1, int kor2);/// You haven't provided an actual definition for this, but your never use it!
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess)/// NOTE: Members are initialized in DECLARATION order!
{
pinakas = new int[korifes];/// Use "[]" (not "()") to allocate an array!
pinakas[0] = 89;/// No need for the dereference (*)
}
Feel free to ask for any further clarification and/or explanation.

recursion and sorting within c++

i did exactly what the pseudo code told me in the book introduction to algorithms and it didn't work
there are two parts that i dont really understand
1-how do u make a recursive function that is a void i mean shouldnt a recursive function always return the last step then what is before it .. it's a void so how would it preform the task
2-merg_sor() was called twice in one function .. do u call that nested recursion ?or what ?? .. and how does it affect the merg function
#include <iostream>
#include <vector>
using namespace std;
void Merg(vector<int> Arr,int start,int middle,int end)
{
std::vector<int> left;
std::vector<int> right;
for(int i =start;i<(end-start);i++)
{
if (i <middle)
{
right.push_back(Arr.at(i));
}
else
{
left.push_back(Arr.at(i));
}
}
int j=0;
int k=0;
for(int i =start;i<(end-start);i++)
{
if(right.at(j)<=Arr.at(i))
{
Arr.at(i)=right.at(j);
j++;
}
else
{
Arr.at(i)=left.at(k);
k++;
}
}
}
void Merg_sort(vector<int> Arr,int start,int end)
{
if (start <end)
{
int middle = (start+end)/2;
Merg_sort(Arr,start,middle);
Merg_sort(Arr,middle+1,end);
Merg(Arr,start,middle,end);
}
}
int main()
{
vector<int> x;
for (int i =0;i<8;i++){x.push_back(i);}
x.at(2)=8;
Merg_sort(x,0,7);
}
1-how do u make a recursive function that is a void i mean shouldnt a recursive function always return the last step then what is before it .. it's a void so how would it preform the task
A function can have side effects. It means, that a function can modify the state of the program. A void function always works by side effects. A void function that doesn't have side effects is completely useless. Whether the function is recursive makes no difference to this question.
2-merg_sor() was called twice in one function .. do u call that nested recursion ?or what ??
I'm not sure if it is commonly used term, but I would describe it as multi-branched recursion.
2 .. and how does it affect the merg function
It doesn't, because it has no side effects.
i did exactly what the pseudo code told me
Perhaps you didn't interpret the pseudo code correctly. Perhaps the arguments are implicitly references in the pseudo-language that you're reading such as they are in languages like python.

Using list made by classes

Well, I just started learning c++ and i seem to have some problem. To be specific i have to make a program that recreates the game musical chairs. For this i was supposed to make two classes one named member that would have the position of a player and their id number and also point to the next (last member should point to first.). Second a class named chain that would point at the first member and also have the total number of exsting players. For starters i should create the chain based on a parametre N that would give every member a random id and position them and of course link the powers with each other.
What i wrote was
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Member{
public:
int position, number;
Member *next_member;
void Member2( Member *member_, int pos, int id,int N){
if(pos <= N){
member_->position=pos;
member_->number=id;
Member2 (member_->next_member, pos++, rand(), N);
if(pos == N)
member_->next_member = this;
}
}
};
class Chain {
Member *First_member;
int size;
public:
Chain ( int N){
size = N;
srand(time(NULL));
First_member->Member2(First_member, 1 , rand(), N);
}
};
and the main just called chain.
The problem is that when Member2 is called by itself, the whole thing crashes. Any help is good.
Edit: When trying to debug it, it seems there is segmentantion fault when membber_ is used after Member2 has called the Member2 isnide it.
The expression pos++ uses post increment, which produces the original value of pos as the expression result. Thus the pos argument does not increase in the recursive call. Thus, you get infinite recursion, which if you're lucky crashes when it's used up all stack space.
There are several issues (at least) with that code:
1)
Member *First_member;
is only a declaration. To turn it into a definition, you need to actually allocate memory, e.g:
Member *First_member = new Member;
and also release it in the end, e.g. (not necessarily the best way to do it, but my C++ is a little rusty):
void free(Member* _member) {
Member* _next = _member->next_member;
if (_next!=NULL) free(_next);
delete _member;
}
Member* First_member = new Member;
// some code ...
free(First_member);
2) More serious problem is your Member2 method: it does not check whether its Member *member_ arguments is not NULL (in which case the code will indeed crash, because it tries to work with garbage as if it was data).
3) Member2 should also take care about allocating memory for the next element in the chain, e.g.:
if (member_->next_member == NULL) {
member->next_member = new Member;
}
Member2 (member_->next_member, pos++, rand(), N);