I am using a vector to represent a deck of cards in c++. I am having trouble shuffling the deck and removing the first element.
Shuffling does not work, the vector keeps the same order. I call reseed once in my program, in the constructor of Deck. int random is different every time. I have tried time(NULL) and time(0). Shuffling:
void Deck::reseed() {
srand(time(NULL));
}
void Deck::shuffle() {
int random = rand();
for(int i = 0; i < random; i++) {
std::random_shuffle(deckVec.begin(), deckVec.end());
}
}
Removing does not work, the last element is removed instead of the first (for example, element 16 is erased and not element 0). Removing:
Card Deck::dealCard() {
//other code...
Card& tempCard = deckVec.front();
std::vector<Card>::iterator temp = deckVec.begin(); //This if for debugging, and
//this pointer is correct
deckVec.erase(deckVec.begin());
return tempCard; //the correct card is returned
}
Any help would be appreciated.
-----------Update----------------
code for printing before and after shuffle:
cout << deck.toString(); //output: Suit: Clubs, Rank: 2
// Suit: Clubs, Rank: 3 ...
//shuffle if there are three arguments
if(argc == 3)
deck.shuffle();
cout << deck.toString();//output: Suit: Clubs, Rank: 2
// Suit: Clubs, Rank: 3 ... (identical to above)
It's difficult to show dealCard. Basically, I call it here:
void operator<<(Hand& hand, Deck& deck) {
hand.addCard(deck.dealCard());
}
Then I print out the contents. The output is: C2 C2 C2 C2 ... for the 2 of Clubs. They are all the first card in the deck.
for(int i = 0; i < 5; i++) {
for(unsigned int j = 0; j < hands.size(); j++) {
try {
hands.at(j) << deck;
} catch(int& i) {
cout << "no cards left" << endl;
}
}
}
//print out the contents
cout << deck.toString() << endl;
for(unsigned int i = 0; i < hands.size(); i++) {
cout << "Hand " << i << ": ";
cout << hands.at(i).toString() << endl;
}
Related
I am taking hard coded information of two arrays and creating the Union, Intersection and Difference of them.
My issue is that I can't get the Intersection or Difference to print with the right format.
I have tried a different variety of while loops with for and if statements, but can't quite get it. I know I'm close-ish. (Hopefully)
Main information:
int setA[] = {3,4,9,12,13,15};
int setB[] = {1,3,5,7,9};
int lenA = sizeof(setA) / sizeof(setA[0]);
int lenB = sizeof(setB) / sizeof(setB[0]);
Difference(setA, setB, lenA, lenB);
Intersection(setA, setB, lenA, lenB);
void Intersection(int setA[], int setB[], int lenA, int lenB)
{
cout << "AnB = {";
for (int i = 0; i < lenA; i++)
{
for (int j = 0; j < lenB; j++)
{
while(setA[i] == setB[j] && i < lenA - 1)
{
cout << setA[i++] << ", ";
}
if(i < lenA && setA[i] == setB[j])
{
cout << setA[i++];
}
}
}
cout << "}";
cout << endl;
}
void Difference(int setA[], int setB[], int lenA, int lenB)
{
cout << "A - B = {";
for (int i = 0; i < lenA; i++)
{
bool comp = false;
for (int j = 0; j < lenB; j++)
if (setA[i] == setB[j])
{
comp = true;
break;
}
if(!comp)
{
cout << setA[i] << ",";
}
}
cout << "}";
cout << endl;
}
I want the output to look like:
AnB = {3, 9} (Intersection)
A-B = {4, 12, 13, 15} (Difference)
What I am getting:
AnB = {3, 9, } (Intersection)
A-B = {4, 12, 13, 15, } (Difference)
I just need to get the commas at the end fixed, but don't know how.
Sorry if this question is way too long, I wasn't sure of how to get my issue out.
I am writing a mpich program for parallel sorting. I need to use the mpi_gather interface, but it doesn't support passing vector of objects. So I use boost_serialization.
Implementation
I use boost_serialization to serialize the vector.
std::string serial_str;
boost::iostreams::back_insert_device<std::string> inserter(serial_str);
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> s(inserter);
boost::archive::binary_oarchive send_ar(s);
//samples is the vector<object>
send_ar << samples;
s.flush();
int len = serial_str.size();
Then, I use mpi_gather to send all the serial_str to root process(data_recv).
char *data_recv = NULL;
if(myid == 0){
data_recv = (char*)malloc(sizeof(char) * (len_all+1));
data_recv[len_all] = '\0';
}
MPI_Gather((void*)serial_str.data(), len, MPI_BYTE, data_recv, len, MPI_BYTE, 0, MPI_COMM_WORLD);
Finally, I deserialize the data in data_recv.
boost::iostreams::basic_array_source<char> device(data_recv,len_all);
boost::iostreams::stream<boost::iostreams::basic_array_source<char>> s(device);
boost::archive::binary_iarchive recv_ar(s);
std::vector<mdata> recv_vec;
recv_ar >> recv_vec;
My implementation is based on How to send a set object in MPI_Send
Problem
I can't deserialize the data in data_recv correctly. I printed the data_recv, then I found the data in data_recv is incorrectly formatted after mpi_gather. The second archive covered the first.(marked in bold)
serialization::archive
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222serialization::archive000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222O#f&!O,t.b X 000000000000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
The correct format should be:(no overlap so I can deserialize)
serialization::archive
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222O#f&!O,t.b X 000000000000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
serialization::archive
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222O#f&!O,t.b X 000000000000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
Question
Why did this happen? Is it because the mpi_gather isn't compatible with c++ object?
If someone could help me out, it would solve my big problem.
Thank you!
code
//processor rank, and total number of processors
int myid, world_size;
//for timing used by root processor
double startwtime = 0.0, endwtime;
//init MPI World
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
//get the processor name
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name,&name_len);
//read local data
std::vector<mdata> mdatas;
string data_path = "/home/jiang/mpi_data";
readAsciiData(data_path, mdatas);
cout <<"rank: "<<myid <<" mdata_vector.size(): "<<mdatas.size()<<endl;
//local sort according ASCII order
std::sort(mdatas.begin(), mdatas.end());
//regular sample
std::vector<mdata> samples;
for(int i=0; i<mdatas.size(); i=i+mdatas.size()/world_size){
samples.push_back(mdatas[i]);
}
//gather the regular samples
//passing data in byte stream by using boost serialization
std::string serial_str;
boost::iostreams::back_insert_device<std::string> inserter(serial_str);
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> s(inserter);
boost::archive::binary_oarchive send_ar(s);
send_ar << samples;
s.flush();
int len = serial_str.size();
//int len = s.str().size();
int *pivot_lens = NULL;
if(myid == 0){
pivot_lens = (int*)malloc(sizeof(int) * world_size);
}
cout <<serial_str <<endl;
//first, gathering the lens and calculate the sum
cout << "rank " << myid << " on "<< processor_name << " is sending len: "<< len << endl;
MPI_Gather(&len, 1, MPI_INT, pivot_lens, 1, MPI_INT, 0, MPI_COMM_WORLD);
//calculate the sum of lens
int len_all = 0;
if(myid == 0){
for(int i=0;i<world_size;i++){
len_all = len_all + pivot_lens[i];
//cout << pivot_lens[i] << endl;
}
cout << "len_all:" << len_all << endl;
free(pivot_lens);
}
//then, gathering string of bytes from all the processes
char *data_recv = NULL;
if(myid == 0){
data_recv = (char*)malloc(sizeof(char) * (len_all+1));
data_recv[len_all] = '\0';
}
MPI_Gather((void*)serial_str.data(), len, MPI_BYTE, data_recv, len, MPI_BYTE, 0, MPI_COMM_WORLD);
// cout << serial_str <<endl;
if(myid == 0){
//deconstructe from byte of string to vector<mdata>
boost::iostreams::basic_array_source<char> device(data_recv,len_all);
boost::iostreams::stream<boost::iostreams::basic_array_source<char>> s(device);
boost::archive::binary_iarchive recv_ar(s);
std::vector<mdata> recv_vec;
recv_ar >> recv_vec;
int count =0;
for(int i=0;i<len_all;i++){
cout<<data_recv[i];
count ++;
}
cout <<endl <<count ;
cout <<endl;
//cout << "rank " << myid << " gets the samples: " << recv_vec.size()<<endl;
iterateForTest(myid, recv_vec);
free(data_recv);
}
MPI_Finalize();
return 0;
I am somewhat new to c++, our class only went over debugging briefly. This is probably my 10th do over, I have been over it a week, have done plenty of research over the web and I just don't understand debugging enough to figure out how to fix my code. The program is supposed to real a file like this:
TTFTFTTTFTFTFFTTFTTF
ABC54102 T FTFTFTTTFTTFTTF TF
DEF56278 TTFTFTTTFTFTFFTTFTTF
ABC42366 TTFTFTTTFTFTFFTTF
ABC42586 TTTTFTTT TFTFFFTF
When it reads the file it's supposed to output the student ids, what they answered on each question and the grade for each student. My problem is, I don't know much about debugging and VS keeps throwing an exception at the end of the code I provided. I am just learning how to use dynamic arrays so I know it has something to do with my use of them because I had the program working fine in my other c++ class but I had to change it around to use dynamic arrays for this project.
What's wrong with my program? I have researched the web and reread the chapters in the book over and over and I cannot figure it out.
#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <cstddef>
using namespace std;
// function prototypes
void readFile(ifstream& inFile);
char assignGrade(int score, int numQues);
int main()
{
int numQues = 20;
int numStud = 0;
string *studentIDs;
studentIDs = new string[numStud];
char *correctAnswers;
correctAnswers = new char[numStud];
char *studentAnswers;
studentAnswers = new char[numQues];
ifstream inFile;
cout << "\nRedo Programming Exercise Six of Chapter Eight\nUsing Dynamic Arrays..." << endl;
cout << "\nPlease Enter the Number of Students: ";
cin >> numStud;
cout << endl;
readFile(inFile);
inFile.getline(correctAnswers, '/n'); // read the correct answers first
for (int i = 0; i < numStud; i++) // loop students
{
inFile >> studentIDs[i]; // get the student ID
inFile.get(); // discard the space between the student ID and the answer
for (int j = 0; j < numQues; j++) // loop questions
{
studentAnswers[j] = inFile.get(); // get the student's answers
}// end for
cout << "Student ID: " << studentIDs[i] << endl; // output student id
int score = 0; // declare and initialize score to zero
cout << "Answers: "; // display "Answers: "
for (int j = 0; j < numQues; j++) // loop each question
{
cout << studentAnswers[j]; // output student's answers
if (studentAnswers[j] == correctAnswers[j]) // if student answer equals correct answer
score += 2; // correct answer
else if (studentAnswers[j] != correctAnswers[j] && studentAnswers[j] != ' ')
score -= 1; // incorrect answer but not a blank
else if (studentAnswers[j] == ' ')
score = 0;
delete[] studentAnswers;
}// end for
if (score < 0)
score = 0; // don't allow for negative scores
cout << endl; // new line, housekeeping
char grade = assignGrade(score, numQues); // call assignGrade function
cout << "Grade: " << grade << "\n" << endl; // display grade
}// end for
delete[] studentIDs;
system("pause");
return(0);
}
void readFile(ifstream& inFile)
{
inFile.open("Ch12_Ex2Data.txt"); // use inFile to open Ch8_Ex6Data.txt
if (!inFile) // if the file can't be opened or it is corrupt
{
cout << "There was an error opening the input file...\nPlease check file and try again!\n" << endl; // display error message
system("pause");
exit(1); // exit the program
}
} // end readFile function
char assignGrade(int score, int numQues)
{
double percentScore = static_cast<double>(score) / (numQues * 2); // calculate the score percentage
cout << "Score: " << percentScore * 100 << "%" << endl; // display the score
if (percentScore >= 0.9) // if score is greater than or equal to 90%, return A
return 'A';
else if (percentScore >= 0.8) // if score is greater than or equal to 80%, return B
return 'B';
else if (percentScore >= 0.7) // if score is greater than or equal to 70%, return C
return 'C';
else if (percentScore >= 0.6) // if score is greater than or equal to 60%, return D
return 'D';
else // any score lower thn 60%, return F
return 'F';
} // end assignGrade function
It keeps breaking here in the debugger:
static void __CLRCALL_OR_CDECL assign(_Elem& _Left, const _Elem& _Right)
_NOEXCEPT
{ // assign an element
_Left = _Right;
}
// Redo Programming Exercise Six of Chapter Eight
// Using Dynamic Arrays -- C++ Advanced
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
// function prototype
void readFile(ifstream& inFile, string fileName);
int main()
{
// variables, pointers and dynamic arrays
int numStud = 200; // stores the number of students, max students was 200
int numQues = 20; // stores the number of questions on test
string *studentIDs; // pointer variable for studentIDs dynamic array
char *correctAnswers; // pointer variable for correctAnswers dynamic array
correctAnswers = new char[numQues]; // correctAnswers dynamic char array
char *studentAnswers; // pointer variable for studentAnswers dynamic array
studentAnswers = new char[numQues]; // studentAnswers dynamic char array
char *fileName; // pointer variable for fileName dynamic char array
fileName = new char[25]; // fileName dynamic char array
ifstream inFile; // input stream variable inFile
// display message to explain the program
cout << "\nJames Flowers - Chapter 12 - Programming Exercise 2" << endl;
cout << "\nRedo Programming Exercise Six of Chapter Eight\nUsing Dynamic Arrays..." << endl;
// request file name for fileName dynamic char array
cout << "\nPlease Enter the File Name (Ch12_Ex2Data.txt): ";
cin >> fileName;
cout << endl;
// call readFile function to read the file
readFile(inFile, fileName);
// request number of students for studentIDs dynamic char array and some calculations
cout << "\nHow many students took this test? (4): ";
cin >> numStud;
cout << endl;
studentIDs = new string[numStud]; // create studentIDs dynamic char array
inFile.getline(correctAnswers, '/n'); // read the correct answers first
for (int i = 0; i < numStud; i++) // loop students
{
inFile >> studentIDs[i]; // get the student ID
inFile.get(); // discard the blank space
inFile.getline(studentAnswers, '/n'); // get the student's test answers
cout << "Student ID: " << studentIDs[i] << endl; // output student id
int score = 0; // declare and initialize score to zero
cout << "Answers: "; // display "Answers: "
for (int j = 0; j < numQues; j++) // loop each question
{
cout << studentAnswers[j]; // output student's answers
if (studentAnswers[j] == correctAnswers[j]) // if student answer is correct
score += 2; // add 2 to score
else if (studentAnswers[j] != correctAnswers[j] && studentAnswers[j] != ' ') // incorrect answer but not blank
score -= 1; // subtract 1 from score
else if (studentAnswers[j] == ' ') // if question left blank
score -= 0; // nothing subtracted from score
studentAnswers[j] = ' '; // clear each indice for next student
}// end for
cout << endl; // new line, housekeeping
char grade = 0; // char variable grade initialized to 0
double percentScore = static_cast<double>(score) / (numQues * 2); // calculate the score percentage
cout << "Score: " << percentScore * 100 << "%" << endl; // display the score
if (percentScore >= 0.9) // if score is greater than or equal to 90%, return A
grade = 'A'; // grade = A
else if (percentScore >= 0.8) // if score is greater than or equal to 80%, return B
grade = 'B'; // grade = B
else if (percentScore >= 0.7) // if score is greater than or equal to 70%,
grade = 'C'; // grade = C
else if (percentScore >= 0.6) // if score is greater than or equal to 60%,
grade = 'D'; // grade = D
else // any score lower than 60%,
grade = 'F'; // grade = F
cout << "Grade: " << grade << "\n" << endl; // display grade
}// end for
system("pause"); // pause for readability
return(0);
}// end main
// readFile function reads the file, if not displays error message
void readFile(ifstream& inFile, string fileName)
{
inFile.open(fileName); // use inFile to open input file
if (!inFile.is_open()) // if the file can't be opened or it is corrupt
{
cout << "There was an error opening the input file...\nPlease check file name and try again!\n" << endl; // display error message
system("pause"); // pause for readability
exit(1);
}// end if
} // end readFile function
I am trying to create a program that asks a user how many babies they have, gather input about each baby, and then displays it on the console. I am 90% of the way there but I am stuck.
The input/output on the console should look like this;
Please enter the number of babies: 2
Please enter baby #1's height : 21.5
Please enter baby #2's height : 19.75
Baby #1's info:
Height: 21.5 inches
Baby #2's info:
Height: 19.75 inches
The output for my code keeps showing 19.75 as the height for both babies. I realize I probably need to use a pointer to dynamically allocate different values to aBaby.height, but I haven't used a pointer within a structure before. Any help would be greatly appreciated.
#include <iostream>
using namespace std;
struct Baby {
double length;
};
int main ()
{
int iNumBaby = 0;
cout<<"Please enter the number of babies: ";
cin>>iNumBaby;
cout<<endl;
Baby aBaby;
Baby* pBaby = new Baby[iNumBaby];
for(int i = 0; i < iNumBaby; i++)
{
cout << "Please enter baby #"<< i + 1 <<"'s height <inches>: ";
cin >> aBaby.length;
cout << "\n";
}
for(int i = 0; i < iNumBaby; i++)
{
cout << "\Baby #"<<i + 1<<"'s info:\n";
cout << "Height: " <<aBaby.length<<" inches"<<endl;
cout << "\n";
}
system("PAUSE");
delete[] pBaby;
return 0;
}
It's nothing to do with pointers, you simply have a bug in your code. See the following block:
for(int i = 0; i < iNumBaby; i++)
{
cout << "Please enter baby #"<< i + 1 <<"'s height <inches>: ";
cin >> aBaby.length;
cout << "\n";
}
The main problem here is that you are storing the entry into aBaby.length every time. In fact, you never used pBaby anywhere in your code. I assume this is what you want:
for(int i = 0; i < iNumBaby; i++)
{
cout << "Please enter baby #" << i + 1 << "'s height <inches>: ";
cin >> pBaby[i].length;
cout << "\n";
}
for(int i = 0; i < iNumBaby; i++)
{
cout << "Baby #" << i + 1 <<"'s info:\n";
cout << "Height: " << pBaby[i].length << " inches" << endl;
cout << "\n";
}
for(int i = 0; i < iNumBaby; i++)
{
cout << "Please enter baby #"<< i + 1 <<"'s height <inches>: ";
cin >> aBaby.length;
cout << "\n";
}
the problem lies in your assignment to aBaby.length. You are assigning every baby's length to the same object. Try accessing the array of babies that you created and change the length of those.
Example:
cin >> pBaby[i].length
#include <iostream>
using namespace std;
int main ()
{
int size = 0;
int* myArray = new int [size + 1];
cout << "Enter the exponent of the first term: ";
cin >> size;
cout << endl;
for (int i = size; i >= 0; --i)
{
cout << "Enter the coefficient of the term with exponent "
<< i << ": ";
cin >> myArray[i];
}
for (int i = size; i >= 0; --i)
{
cout << i << endl;
}
return 0;
}
Why am I getting an assertion error on input greater than 2? This is the precursor to a polynomial program where the subscript of the array is the power of each term and the element at array[subscript] is the coefficient.
Your array is allocated to be an int[1]. It needs to be allocated after you read in the size value.
You are initializing your array when size = 0, giving an array size of 1
You get your assertion error when you go outside of the array bounds (1).
myArray always has size 0 + 1 = 1. i starts out at whatever the user inputted, and the first array access you make is myArray[i]. So, say the user inputs 5, your array has size 1 and you access myArray[5]. It will fail!
I would allocate the array AFTER you input size.