C++ Insertion Sort a vector - c++

I'm trying to do an insertion sort on a vector of baseball pitchers I created yesterday with help from a previous post. I want to sort the pitchers in ascending order by ERA1. I have gotten the insertion sort to work in the past for a set of integers. I think I have a syntax error in my code for the insertion sort. Up until trying to add the insertion sort this program was working well. I get an error - expected unqualified id before [ token. Thanks in advance for any help.
#ifndef Pitcher_H
#define Pitcher_H
#include <string>
#include <vector>
using namespace std;
class Pitcher
{
private:
string _name;
double _ERA1;
double _ERA2;
public:
Pitcher();
Pitcher(string, double, double);
vector<Pitcher> Pitchers;
string GetName();
double GetERA1();
double GetERA2();
void InsertionSort(vector<Pitcher>&);
~Pitcher();
};
#endif
#include "Pitcher.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
Pitcher::Pitcher()
{
}
Pitcher::~Pitcher()
{
}
string Pitcher::GetName()
{
return _name;
}
Pitcher::Pitcher(string name, double ERA1, double ERA2)
{
_name = name;
_ERA1 = ERA1;
_ERA2 = ERA2;
}
double Pitcher::GetERA1()
{
return _ERA1;
}
double Pitcher::GetERA2()
{
return _ERA2;
}
#include "Pitcher.h"
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
void InsertionSort(vector<Pitcher> Pitchers&);
using namespace std;
int main()
{
vector<Pitcher> Pitchers;
cout << "Pitcher" << setw(19) << "Item ERA1" << setw(13) <<
"Item ERA2\n" << endl;
Pitcher h2("Bob Jones", 1.32, 3.49);
Pitchers.push_back(h2);
Pitcher h3("F Mason", 7.34, 2.07);
Pitchers.push_back(h3);
Pitcher h1("RA Dice", 0.98, 6.44);
Pitchers.push_back(h1);
for(unsigned i = 0; i < Pitchers.size(); ++i)
{
cout << setw(19);
cout << left << Pitchers[i].GetName() << "$" <<
setw(10) << Pitchers[i].GetERA1() <<
right << "$" << Pitchers[i].GetERA2() << "\n";
}
cout << endl;
//------------------------------------------------------
InsertionSort(Pitchers);
//Now print the numbers
cout<<"The numbers in the vector after the sort are:"<<endl;
for(int i = 0; i < Pitchers.size(); i++)
{
cout<<Pitchers[i].GetERA1()<<" ";
}
cout<<endl<<endl;
system("PAUSE");
return 0;
}
void InsertionSort(vector<Pitcher> &Pitchers)
{
int firstOutOfOrder = 0;
int location = 0;
int temp;
int totalComparisons = 0; //debug purposes
for(firstOutOfOrder = 1; firstOutOfOrder < Pitchers.size() ; firstOutOfOrder++)
{
if(Pitcher.GetERA1([firstOutOfOrder]) < Pitcher.GetERA1[firstOutOfOrder - 1])
{
temp = Pitcher[firstOutOfOrder];
location = firstOutOfOrder;
do
{
totalComparisons++;
Pitcher.GetERA1[location] = Pitcher.GetERA1[location - 1];
location--;
}while(location > 0 && Pitcher.GetERA1[location - 1] > temp);
Pitcher.GetERA1[location] = temp;
}
}
cout<<endl<<endl<<"Comparisons: "<<totalComparisons<<endl<<endl;
}

Here:
for(firstOutOfOrder = 1; firstOutOfOrder < Pitchers.size() ; firstOutOfOrder++)
{
if(Pitchers[firstOutOfOrder].GetERA1() < Pitchers[firstOutOfOrder-1].GetERA1())
{ //^^^your way was not right, should first access the object then
//access member function
temp = Pitcher[firstOutOfOrder];
//^^^should be Pitchers, similar errors below
location = firstOutOfOrder;
do
{
totalComparisons++;
Pitcher.GetERA1[location] = Pitcher.GetERA1[location - 1];
//^^^similar error as inside if condition
location--;
}while(location > 0 && Pitcher.GetERA1[location - 1] > temp);
//^^^similar error as inside if condition
Pitcher.GetERA1[location] = temp;
//^^similar error as in if condition and name error
}
}
Meanwhile, you put the InsertionSort declaration as a member of the Pitcher class
public:
.
.
void InsertionSort(vector<Pitcher>&);
and you also declare the same function inside main,
void InsertionSort(vector<Pitcher> Pitchers&);
//should be vector<Pitcher>& Pitchers
using namespace std;
int main()
the member function probably should be removed in your case. InsertionSort is not a responsibility of your Pitcher class.

Unless this is homework, you're better off using the build in sort from
<algorithm>

Related

Create Multiple Objects in a loop c++

I'm a beginner and was researching to find out if you can grab a name from an array to then put that name as the name of the object in a for loop.
The code a specifically created for this question is represented below:
#include <iostream>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
for(int i = 0; i < 4; i++) {
YourMum names[i];
cout << names[i].name << endl;
cout << "You are great if you answer my question!";
}
return 0;
}
Okay, it's not clear what you're trying to do, but you've got a few things that aren't a good idea.
First, you defined string names[5] and then inside loop you hid names by making a second variable with the same name. While that's legal, it's a bad practice.
Second, you're using the second one (YourMum names) illegally:
You declared it as length i (using a non-standard feature of the compiler) but then reference element i. The elements of an array of length i range from 0..i-1, so [i] is one element past the end.
And you haven't initialized it anyway.
I'm not really clear what you're trying to do, so I can't even provide example code of how to do it.
The YourMum class you have shown is not default constructible, so YourMum names[size]; will not work. Every object of YourMum needs to be passed a parameter in order to create it. You can use placement-new for that, eg:
#include <iostream>
#include <type_traits>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
std::aligned_storage<sizeof(YourMum), alignof(YourMum)>::type arr[5];
YourMum *mums = reinterpret_cast<YourMum*>(arr);
for(int i = 0; i < 5; i++) {
new (&mums[i]) YourMum(names[i]);
}
for(int i = 0; i < 5; i++) {
cout << mums[i].name << endl;
cout << "You are great if you answer my question!";
}
for(int i = 0; i < 5; i++) {
mums[i].~YourMum();
}
return 0;
}
Or, you can use std::vector instead:
#include <iostream>
#include <vector>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
std::vector<YourMum> mums;
mums.reserve(5);
for(int i = 0; i < 5; i++) {
mums.emplace_back(names[i]);
}
for(int i = 0; i < 5; i++) {
cout << mums[i].name << endl;
cout << "You are great if you answer my question!";
}
return 0;
}
First of all, you should rename the name variable to something like _name or name_ for lisibility (to differenciate it from variables that aren't in the class), and you should also use the private section of your class to declare it and use getters/setters functions to edit it. Secondly, in your code you are declaring the object inside a loop, so it will get destroyed as soon as the loop iterates again, so if you want to create n objects in a loop and interact with them after you should either use a container class (like std::vector) or use a default constructor (which is better). Here is an updated version of your code:
#include <iostream>
#include <string>
class YourMum
{
public:
YourMum(void) : _name() { }
YourMum(std::string name) : _name(name) { }
std::string getName(void) const { return _name; }
void setName(std::string name) { _name = name; }
private:
std::string _name;
};
int main()
{
std::string names[5] = { "Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum" };
YourMum mums[5];
for (int i = 0; i < 5; i++)
{
mums[i].setName(names[i]);
std::cout << mums[i].getName() << std::endl
<< "You are great if you answer my question!" << std::endl;
}
// this way you can still access mums here if you want to
return 0;
}
If you want to access to a class by it's name as index what you can also do is using std::map like this
#include <map>
int main()
{
std::string names[5] = { "Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum" };
std::map <std::string, YourMum> mums;
for (int i = 0; i < 5; i++)
mums[names[i]] = YourMum(names[i]);
std::cout << mums["Jeremy_Clarkson"].getName() << std::endl;
return 0;
}
Try This
> for(int i = 0; i < 4; i++) {
> YourMum name(names[i]);
>
> cout << name.name << endl;
> cout << "You are great if you answer my question!";
> }

Why does this happen c++ [duplicate]

This question already has answers here:
string and int concatenation in C++ [duplicate]
(3 answers)
Closed 2 years ago.
Hello I am trying to make a game somewhat like Pokemon but I'm stuck on printing stats.
I am trying to output a level with it showing what level the animal reached.
Any help on the fact I'm not getting expected results?
My code:
visualanimal.h (not used yet):
#include <string>
#ifndef VISUALANIMAL_H
#define VISUALANIMAL_H
using namespace std;
using namespace Animals;
/*** Visual based on original class
#author Adam Petla
***/
class VisualAnimal : Animal {
public:
string imageFileURL;
int size;
VisualAnimal() {
this->imageFileURL = "";
this->size = 0;
}
};
#endif
animal.h :
#include <string>
#include <stdio.h>
#include <iostream>
#ifndef ANIMAL_H
#define ANIMAL_H
using namespace std;
namespace Animals {
class Animal {
public:
string name;
int minlevel;
int level;
int maxlevel;
int baseattack;
int baseattackraise;
int attack;
int basedefense;
int basedefenseraise;
int defense;
int basespeed;
int basesppedraise;
int speed;
int basespecial;
int basespecialraise;
int special;
char type;
Animal() {
name = "DOG";
minlevel = 0;
level = 1;
maxlevel = 100;
baseattack = 1;
baseattackraise = 1;
basedefense = 1;
basedefenseraise = 1;
basespecial = 1;
basespecialraise = 1;
basespeed = 1;
basesppedraise = 1;
};
private:
void printstats() {
//cout << "Attack : " << this->
};
void raiseattack() {
this->attack += this->baseattackraise;
}
void raisedefense() {
this->defense += this->basedefenseraise ;
}
void raisespeed() {
this->speed += this->basesppedraise;
}
void raisespecial() {
this->special += this->basespecialraise;
}
void raisestats() {
raiseattack();
raisedefense();
raisespeed();
raisespecial();
}
void updatestats(char type) {
switch (type) {
case 'l':
raisestats();
}
}
public :
void raiselevel() {
this->level++ ;
this->type = 'l';
updatestats(this->type);
string output = "Level Up!Your " + string(this->name) + string("has reached level");
cout << output;
cout << this->level + ".Its stats are now";
printstats();
};
};
}
#endif
animal.cpp :
// Animals.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include "animal.h"
#include "visualanimal.h"
using namespace std;
int main()
{
using namespace`` Animals;
Animal test;
test.raiselevel();
cout << "Hello World!\n";
return -1;
}
My expected results: DOG reached level 2.
My actual results DOG reached level
Anybody know an answer
It doesn't show any level in output anybody know why?
Change the following:
cout << this->level + ".Its stats are now";
To:
cout << this->level << ".Its stats are now";
You were getting incorrect output because you are trying to concatenate a string and an int.
The correct way to concatenate a string to an int is using std::to_string():
int val = 2;
std::string x = "hello";
std::string output = std::to_string(val) + x;
+ has a higher precedence than <<, so the line cout << this->level + ".Its stats are now"; is evaluated as cout << (this->level + ".Its stats are now"); - the value of level is used as an offset into a string literal ".Its stats are now", which is not what you want.
Change it to
cout << this->level << ".Its stats are now";
Or see here how to concatenate an int with a string.

Read access violation?

I am writing some C++ code to create an item of a class i have created inside a vector of another class. I seem to be able to create the items inside the vector but when i try to read a variable of the item inside the vector i get the error
Exception thrown: read access violation.
_Right_data was 0x8.
inside the document xstring.
I think it might have something to do with me not actually creating each team inside the vector.
the code i have written that is relavent is
for (int x = 1; x <= mainLeague.getNumTeams(); x++) {
std::cout << "please enter the name of team " << x << ":";
std::getline(std::cin, currLine);
parsed = parseText(currLine, &posResponsesTeamNames);
if (parsed == 2) {
prepForEnd();
return 1;
}
else if (parsed == 0) goto enterTeamNames;
mainLeague.createTeam(currLine);
}
std::cout << mainLeague.getName(5);
}
#pragma once
#include "team.h"
#include <string>
#include <vector>
#include <iostream>
class league
{
std::vector<team*> teams;
int numTeams, numInitTeams = 0;
const float sysCon = 0.5;
public:
league(int a);
int getNumTeams();
void initVector(int numTeams);
void createTeam(std::string name);
std::string getName(int num);
};
void league::createTeam(std::string name)
{
if (numInitTeams < teams.size()) {
team currTeam = team::team(name);
teams.at(numInitTeams) = &currTeam;
numInitTeams;
}
else {
std::cout << "error max amount of teams already created";
}
}
#pragma once
#include<string>
class team
{
float RD;
int rating;
std::string name;
public:
team(std::string name);
team();
std::string getName();
};
std::string team::getName()
{
return team::name;
}

Object member variable updating in function but not persisting

I am fairly new to c++ and building a simple battleship game. I have a function that initializes the ship types and lengths by taking in a vector of ship objects. I have confirmed that the type and ship length are updating inside the function but the changes are not persisting in the main function. Any help would be greatly appreciated.
#include <iostream>
#include <vector>
#include "ships.h"
#include "board.h"
#include "player.h"
using std::vector;
void initialize_ships(vector<ship> &newFleet)
{
vector<string> ship_types = { "carrier","battleship","submarine","cruiser","destroyer" };
for (auto ii = 0; ii != newFleet.size(); ++ii)
{
newFleet[ii].type = ship_types[ii];
newFleet[ii].setLength();
if (newFleet[ii].type == "carrier")
{
std::cout << "Carrier in function has type: " << newFleet[ii].type << std::endl;
}
}
}
int main()
{
ship player_carrier, player_battleship, player_submarine, player_cruiser, player_destroyer;
vector<ship> player_fleet = {player_carrier, player_battleship, player_submarine, player_cruiser, player_destroyer };
initialize_ships(player_fleet);
std::cout << "Carrier in main has type: " << player_carrier.type << std::endl;
system("pause");
return 0;
}
#ifndef SHIPS_H
#define SHIPS_H
#include <iostream>
#include <string>
using std::string;
struct ship
{
// ships member variables
int len;
char dir;
int health;
int row;
int col;
char symb;
string type;
void setLength()
{
if (type == "carrier")
{
len = 5;
}
else if (type == "battleship")
{
len = 4;
}
else if (type == "cruiser")
{
len = 3;
}
else if (type == "submarine")
{
len = 3;
}
else if (type == "destroyer")
{
len = 2;
}
else
{
std::cout << "Invalid ship type!" << std::endl;
}
}
};
#endif // SHIPS_H
Accidentally making copies is a common reason for changes to be “lost”. For this particular situation, where you want to have objects in a container and have names for those objects (as if they were members of a class), the sensible thing to do is to make references to objects in the container:
vector<ship> player_fleet(5);
ship &player_carrier=player_fleet[0],
&player_battleship=player_fleet[1],
&player_submarine=player_fleet[2],
&player_cruiser=player_fleet[3],
&player_destroyer=player_fleet[4];
Be careful not to cause the vector to reallocate, since that would invalidate your references. (Of course, if it never changes size, ship player_fleet[5]; would suffice.)

Seg Fault with Class Constructors C++

I am new to classes and am having a lot of difficulty with the constructors. I have two constructors for a business class and whenever I attempt to create a business object or do anything with the business object I immediately Seg Fault. The business class interacts with an additional class called Customer. If anyone could offer any help I would greatly appreciate it.
Business.h
#ifndef BUSINESS_H
#define BUSINESS_H
#include <iostream>
#include <string>
#include "customer.h"
using namespace std;
class Business
{
public:
Business();
Business(string name, float cash);
void printData() const;
void addCustomer(Customer newCustomer);
void make_a_sale();
private:
string businessName;
float cashInReg;
string itemArray[10];
Customer custInBus[10];
short numOfItems;
short numOfCustom;
};
#endif
Business.cpp
#include "business.h"
#include <iostream>
#include <cstdlib>
using namespace std;
Business::Business(): businessName("Business"), cashInReg(0), numOfItems(0),
numOfCustom(0) {}
Business::Business(string name, float cash) : businessName(name),
cashInReg(cash), numOfCustom(0) {}
void Business::printData() const
{
cout << businessName <<endl;
for (int i=0; i<numOfCustom; i++)
{
cout << "\t Customer Name: " << custInBus[i].getName() <<endl;
}
for (int i=0; i<numOfItems; i++)
{
cout << "\t Item list: " <<itemArray[i] <<endl;
}
}
void Business::addCustomer(Customer newCustomer)
{
custInBus[numOfCustom-1] = newCustomer;
numOfCustom++;
}
void Business::make_a_sale()
{
int randomItem;
int currCustomer=0;
while (currCustomer < numOfCustom)
{
randomItem = rand() %tempItems;
custInBus[currCustomer].purchase(tempArray[randomItem]);
currCustomer ++;
}
}
void Business::addCustomer(Customer newCustomer)
{
custInBus[numOfCustom] = newCustomer;
//use numOfCustom instead of numOfCustom-1
numOfCustom++;
}