I'm trying to implement selection sort as a member function within class, to sort the objects of the class where the number of total players are being got by user input, also the names and scores of the players are being got by user too.
I'll sort the player objects by the property of their scores, which is a class member, being got by user input.
My problem is, i got stuck within the main where i can't call the class' member function sort for the array of objects.
class Player{
private:
string name;
int score;
public:
void setStatistics(string, int) // simple setter, not writing the whole function
void sortPrint(int, Player []);
int getScore(){ return score; }
void print(){ cout << name << " " << score << endl; }
};
void Player::sortPrint(int n, Player arr[]){
int i, j, minIndex;
Player tmp;
for (i = 0; i < n - 1; i++) {
int maxIndex = i;
for (j = i + 1; j < n; j++)
{
if (arr[j].getScore() > arr[minIndex].getScore())
{
minIndex = j;
}
}
if (minIndex != i) {
tmp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = tmp;
}
for(int i=0; i<n; i++){
arr[i].print(); // not sure with this too
}
}
};
int main(){
int n,score;
string name;
cout << "How many players ?" << endl;
cin >> n;
Player **players;
players = new Player*[n];
for(int i=0;i<n;i++) {
cout << "Player's name :" << endl;
cin >> name;
cout << "Player's total score:" << endl;
cin >> score;
players[i] = new Player;
players[i]->setStatistics(name,score);
}
for(int i=0; i<n;i++){
players->sortPrint(n, players); // error here, dont know how to do this part
}
// returning the memory here, didn't write this part too.
}
Try to replace void Player::sortPrint(int n, Player arr[]) with void Player::sortPrint(int n, Player*) and call function like players->sortPrint(n, *players)
Your problem is, that players is a pointer to array of Player, and arrays do not have member functions of the containees. As Player::sortPrint does not depend on the object itself, declare it as static and call it like Player::sortPrint(n, players);
Unless you have a very good reason not to, you should use std::sort rather than your own sorting algorithm. You should use a comparison function which compares the score of each player.
The following should work in C++03:
bool comparePlayerScores(const Player* a, const player* b)
{
return (a->getScore() < b->getScore());
}
// Returns the players sorted by score, in a new std::vector
std::vector<Player*> getSortedPlayers(Player **players, int num_players)
{
std::vector<Player*> players_copy(players, players + num_players);
std::sort(players_copy.begin(), players_copy.end(), comparePlayerScores);
return players_copy;
}
void printSorted(Player **players, int num_players)
{
std::vector<Player*> sorted_players = getSortedPlayers(players, num_players);
// Could use iterators here, omitting for brevity
for (int i = 0; i < num_players; i++) {
sorted_players[i]->print();
}
}
(Alternatively, you could define an operator< on your Player class which compares scores, which would let you store players in a std::set or std::map.)
Related
I need help with this code.
What I want is to make a parametric constructor and initialise/set the value of array in it.
Question: Make a class with arrays of integers and initialise it in a constructor. Then find the smallest and largest numbers using functions.
But I am stuck at how to initialise the array in the constructor.
I want to take data input in both ways
(1) By user, using cin
(2) By giving my own values
class Numbers
{
int Arr[3];
public:
Numbers() //default constructor
{
for (int i=0 ; i<=2 ; i++)
{
Arr[i]=0;
}
}
Numbers(int arr[]) //parameteric constructor
{
for (int i=0;i<=2;i++)
{
Arr[i]=arr[i];
}
}
};
int main()
{
int aro[3] = {0,10,5};
Numbers obj (aro);
return ;
}
The solution is pretty simple. I've made a new program from start again (for sake of understanding). According to your requirement, you wants to get input of array elements from the user dynamically and assign them to a constructor and use a method to print the highest value.
Consider the following code:
#include <iostream>
using namespace std;
const int N = 100;
class Numbers
{
int largest = 0;
public:
Numbers(int, int[]);
void showHighest(void)
{
cout << largest << endl;
}
};
Numbers::Numbers(int size, int arr[])
{
for (int i = 0; i < size; i++)
{
if (arr[i] > largest)
{
largest = arr[i];
}
}
}
int main(void)
{
int arrays[N], total;
cout << "How many elements? (starts from zero) ";
cin >> total;
for (int i = 0; i < total; i++)
{
cout << "Element " << i << ": ";
cin >> arrays[i];
}
Numbers n(total, arrays);
n.showHighest();
return 0;
}
Output
How many elements? (starts from zero) 3
Element 0: 12
Element 1: 16
Element 2: 11
16
Note: I've initialized a constant number of maximum elements, you can modify it. No vectors, etc. required to achieve so. You can either use your own values by removing the total and its followed statements and use only int arrays[<num>] = {...} instead. You're done!
Enjoy coding!
I suggest to use std::vector<int> or std::array<int>.
If you want initialize with custom values you can do std::vector<int> m_vec {0, 1, 2};
Thank you so much for your help. I was basically confused about how to use arrays in a constructor and use setters/getters for arrays in a class. But you all helped a lot. Thanks again.
Numbers(int arr[])
{
for (int i=0;i<=9;i++)
{
Arr[i]=arr[i];
}
Largest=Arr[0];
Smallest=Arr[0];
}
void Largest_Number()
{
header_top("Largest Number");
Largest=Arr[0]; //Using this so we make largest value as index zero
for (int i=0 ; i<=9 ; i++)
{
if(Arr[i]>Largest)
{
setLargest( Arr[i] );
}
}
cout<<"Largest Number: "<<getLargest()<<endl;
}
Here is the code I'm trying to create, and yes its messy for now. To give some back story I'm trying to figure out how to call a class multiple times without doing it seperately. What I mean is instead of performing:
Dice diceOne;
Dice diceTwo; and so on, I want to know if it is possible to just put it as Dice dicewhatever(*) and have that be a modifiable variable. This is so that I can set that variable to a number and then decrement it based on a score.
I dont know if this is even possible, but at this point I've beat my head against this so much I'm just pulling at straws to see if it would be a fit.
class Dice {
public:
Dice();
int Roll();
int currentDiceSide();
private:
int diceRoll;
int diceReRoll; //Declares and initializes the number of dice to allow for roll next dice throw.
};
Dice::Dice()
: //This is the beginning of the class and sets diceRoll to zero
diceRoll(0)
{
}
int Dice::Roll()
{ //This function actually does the random roll within the class Dice.
diceRoll = ((rand() % 6) + 1);
return diceRoll;
}
int Dice::currentDiceSide()
{ //This function returns the value of the dice roll for the class call.
return diceRoll;
}
void Game::Rules()
{
ifstream inFile;
inFile.open("Farkle Rules.txt");
string line;
if (inFile.fail()) {
cerr << "Error opening file" << endl;
exit(1);
}
if (inFile.is_open()) {
while (inFile.good()) {
getline(inFile, line);
cout << line << endl;
}
inFile.close();
}
}
void Game::GetPlayerInput(int playerInput)
{
cin >> playerInput;
}
void Game::RunGame()
{
Rules();
bool farkle = false;
double turnSum = 0;
double value = 0;
int i = 0;
int w = 6;
int players = 0;
int numPlayer = 0;
int diceOneValue = 0;
int diceTwoValue = 0;
int diceThreeValue = 0;
int diceFourValue = 0;
int diceFiveValue = 0;
int diceSixValue = 0;
int num1s = 0; //Declaring and initializing the variables to hold how many times a number shows up in a roll.
int num2s = 0;
int num3s = 0;
int num4s = 0;
int num5s = 0;
int num6s = 0; //
srand(static_cast<unsigned int>(time(0)));
cout << "Welcome to Farkle!" << endl
<< endl;
cout << "Please enter the number of players " << endl;
cin >> players;
//Dice diceOne;
//diceOne.currentDiceSide();
//Dice diceTwo;
//diceTwo.currentDiceSide();
//Dice diceThree;
//diceThree.currentDiceSide();
//Dice diceFour;
//diceFour.currentDiceSide();
//Dice diceFive;
//diceFive.currentDiceSide();
//Dice diceSix;
//diceSix.currentDiceSide();
Dice diceOne(w);
< -this is the line that I would like to create with a variable that is modifiable.
You cannot give each Dice object a name, but you can create a Vector of Dice object pointers (vectors are basically resizable arrays), like this:
#include <vector>
#include <iostream>
//...
std::cout << "Please enter the number of players " << std::endl;
std::cin >> players;
// do something to make sure players is an integer
// initialize the empty playerDice vector
std::vector<Dice*> playerDice = {};
for (unsigned i = 0; i < players; ++i) {
playerDice.push_back(new Dice); // this adds a new Dice object pointer to the end of the vector
playerDice.at(i)->currentDiceSide();
}
You have then called the currentDiceSide() function on each Dice object you created, and have neatly organized them in a Vector, which you can access like this:
// say we want to access the third Dice Object,
// Vectors start counting at 0, so we acces the element at Index 2.
playerDice.at(2)->doSomething();
Now because you instantiated those Dice objects with new you have to remember to delete them when you're finished with them, otherwise this will create a memory leak.
//...
// this deletes all the Dice objects in the vector, and points the remaining pointers to null
for (auto d : playerDice) {
delete d;
d = nullptr;
}
Or, better yet, if you're using C++11, you can use std::unique_ptr instead of the raw C-style pointers. Those will prevent you from creating memory leaks, because they will be deleted when they go out of scope. Note you have to #include <memory> to use these.
The vector definition then turns into:
std::vector< std::unique_ptr<Dice> > playerDice = {};
And the creation of the objects would look like this
for (unsigned i = 0; i < players; ++i) {
Dice* temp = new Dice;
temp->currentDiceSide();
std::unique_ptr<Dice> uPtr{ temp };
playerDice.push_back(std::move(uPtr));
}
You can then just clear the vector when you're done with all the objects:
playerDice.clear();
which will delete all the Dice objects that you put into the vector.
There is a few lines of my code that I would like to define as a function because I plan to use it multiple times. portion of code is as follows:
// loop within loop used to reorder with highest price at the top
for(i=0;i<x;i++){
for(t=i;t<x;t++){
if(f[i].price < f[t].price) {
temp = f[i].price;
f[i].price = f[t].price;
f[t].price = temp;
}
}
}
I hope to be able to enter new values for x and f each time I call the function. I have included all of my code below. If I'm unclear about my objective in anyway please feel free to ask. I apologize in advance for the improper terminology I am new to this. Thank you
#include <iostream>
using namespace std;
struct List
{
char name[10];
int price;
};
int main()
{
//x represents number of structures within array!
int x;
cout << "How many items would you like to list under the fruit menu?\n";
cin >> x;
//array of structures fruit
struct List f[x];
int i;
//input values into structure
for (i = 0; i < x; i++) {
cout << "\nEnter fruit name, and price.\n";
cin >> f[i].name;
cin >> f[i].price;
};
//variables for reordering
int temp;
int t;
// loop within loop used to reorder with highest price at the top
for(i=0;i<x;i++){
for(t=i;t<x;t++){
if(f[i].price < f[t].price) {
temp = f[i].price;
f[i].price = f[t].price;
f[t].price = temp;
}
}
}
//Output of menus
//fruit Menu
cout << "\n\nFruit Menu";
for (i = 0; i < x; i++) {
cout << "\n" << f[i].name << " $" << f[i]. price;
};
return 0;
}
I suppose it is an assignment that says "implement your own sort function for sorting an array of fruits", so I take the data structure "array of fruits" as given. You can, of course, change this to vector<struct Fruit> as well, but that's a different topic.
Maybe the following fragments help you finishing your code. It contains functions for entering, sorting, and printing the array with some samples how to deal with the parameters and the calls. You'll have to finalise the code.
Have fun!
#include <iostream>
using namespace std;
struct Fruit
{
char name[10];
int price;
};
// enter up to nrOfFruis; return number of fruits actually entered
int enterFruits(struct Fruit *fruits, int maxNrOfFruits) {
int entered = 0;
while (entered < maxNrOfFruits) {
cin >> fruits[entered].name;
entered++;
}
return entered;
}
void sortFruits(struct Fruit* fruits, int nrOfFruits) {
// your sort code goes here
// example for swaping two elements:
Fruit temp = fruits[0];
fruits[0] = fruits[1];
fruits[1] = temp;
}
void printFruits(struct Fruit *fruits, int nrOfFruits) {
cout << "\n\nFruit Menu";
for (int i = 0; i < nrOfFruits; i++) {
cout << "\n" << fruits[i].name << " $" << fruits[i]. price;
};
}
int main()
{
// Your task: put a proper loop and exit condition arround the following lines...
int x;
cout << "How many items would you like to list under the fruit menu?\n";
cin >> x;
struct Fruit fruits[x];
int entered = enterFruits(fruits, x);
sortFruits(fruits, entered);
printFruits(fruits, entered);
return 0;
}
You cannot allocate an array on the stack if you do not know it's size at compile time. Therefore, you need to dynamically allocate memory for it(you also need to remember to delete it):
//x represents number of structures within array!
int x;
cout << "How many items would you like to list under the fruit menu?\n";
cin >> x;
//array of structures fruit
struct List * f = new List[x];
//...
delete [] f;
Alternatively, you could do it the C++ way, using vector, having the vector elements on the stack:
int x;
std::cin>>x;
std::vector<A> v(x);
for( size_t i = 0; i < x; i++)
{
std::cin >> v[i].x;
}
If you just want to pass an array to a function you can do so like this:
void sortArray(struct List list[]);
void sortArray(struct List* list, int n); // n = size of array
may be better to just use std::vector or some other list container instead. :)
Sounds like you want a function that receives an array t and index x, and you want to mutate the array in the function?
C++ is "pass by value", so to mutate the array you have to have your function take a reference (or pointer) to the array so that you're mutating the original array and not a copy of it, so just have your function signature like this: func(T& t, int x) (assuming T is the type of array t).
Hello I'm having this issue with my C++ problem I'm working on.
Here is the code
Cell.h
#ifndef CELL_H
#define CELL_H
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Cell
{
private:
int level;
int row;
int column;
//declares a variable called ptrFunction_array which is an array of 3 function pointers.
typedef void (*ptrFunction[])(void);
static void function1()
{
cout << "I'm function 1";
}
static void function2()
{
cout << "I'm function 2";
}
static void function3()
{
cout << "I'm function 3";
}
public:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction = new *fArray[3];
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
virtual ~Cell();
void tick()
{
int randomNumber = rand() % 3;
cout << "Cell(" << level << ", " << row << ", " << column << ") ";
fArray[randomNumber];
}
};
#endif // CELL_H
Main.cpp
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "Cell.h"
using namespace std;
Cell ****myArray;
int main()
{
int level = 0;
int row = 0;
int column = 0;
char userInput = 'y';
srand (time(NULL));
do
{
cout << "Please input the amount of levels: ";
cin >> level;
cout << "Please input the amount of rows: ";
cin >> row;
cout << "Please input the amount of columns: ";
cin >> column;
cout << endl;
myArray = new Cell *** [level];
// Set random number to the elements of the array
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
myArray [currentLevel] = new Cell ** [row];
for (int currentRow = 0; currentRow < row; currentRow++)
{
myArray [currentLevel][currentRow] = new Cell * [column];
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
myArray [currentLevel][currentRow][currentColumn] = new Cell (currentLevel, currentRow, currentColumn);
myArray [currentLevel][currentRow][currentColumn] -> tick();
cout << " ";
}
cout << endl;
}
cout << endl;
}
cout << "Do you want to try again? (y / n) ";
cin >> userInput;
cout << endl;
if ((userInput == 'y') || (userInput == 'Y'))
{
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
for (int currentRow = 0; currentRow < row; currentRow++)
{
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
delete[] myArray[currentLevel][currentRow][currentColumn];
}
delete[] myArray[currentLevel][currentRow];
}
delete[] myArray[currentLevel];
}
delete[] myArray;
myArray = NULL;
}
}while (userInput != 'n');
return 0;
}
I notice that my fArray isn't inside the scope. the Line ptrFunction = new *fArray[3]; is where my error is. I've recently started learning C++ so I'm in the process of trying to understand why my typedef void (*ptrFunction[])(void); isn't correctly initializing the fArrayfor my program. The goal of my program is to be able to create a 3 dimensional array and be able to point to the Cell Objects and be able to track the location x,y,z.
Why does an error like this happen?
I'm going to ignore the four star pointer for now and stick to what's giving OP the most immediate grief.
A quick walk-through:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
Not bad to here. But...
ptrFunction = new *fArray[3];
This says assign to the variable ptrFunction, which must already exist and doesn't, a newly allocated array of 3 fArrays. The problem here is ptrFunction has been defined as a type, not a variable. fArray is not a type.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
Use fArray as a variable, making what's gone wrong here somewhat clear.
}
Cell needs to look a bit more like this, but not exactly. More on that later.
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction * fArray = new ptrFunction[3];
Now fArray is a variable that points to one or more objects of type ptrFunction (but the definition of ptrFunction is somewhat broken), and points fArray at three ptrFunctions. Technically it points at the first of three ptrFunctions.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
Now we have an fArray, but it is a local variable and it only exists between the curly braces of Cell's constructor. When the constructor exists, the pointer goes away. The memory allocated does not and is lost. Without fArray pointing to it, you can't easily find it to use or delete it. fArray needs wider scope so that A) the memory isn't lost, and B) so that tick and other members of Cell can see it.
class Cell
{
private:
ptrFunction * fArray;
int level;
and in the constructor:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
fArray = new ptrFunction[3];
That fixes the can't find fArray.
My recommendation is to get one Cell working and then take a stab at getting a 1 dimensional array of Cells working. When you have one dimension, then try two. You might find that's all you need.
Edit
Forgot to mention this: Function pointers to members functions are an absolute expletive deleted to get right. Here is a page on common pitfalls and how to avoid them.
And here is how we avoid this smurf in the here and now of Modern C++: std::bind and std::function. The tutorials at the bottom of the linked document pages probably describe how to use them for simple cases better than I can.
I'm trying to implement a quicksort and am having some trouble. Ultimately, the sort will alphabetize a string vector and in turn synchronize a second vector with it so they stay matched (which should be easy since it's just repeating the same line with a different vector argument.)
At first when I compiled and ran the program, it was just generating the same output as before. I realized that this was because when I declared the vectors I didn't use the object.member notation. I modified it, and now I'm getting a compiler error.
in function int main
in lookup_member, at cp/search.c:1288
Obviously, there's a problem when it's trying to look at the vectors, but I'm not sure what.
I got my implementation of the quicksort code from Quick Sort (MathBits.com).
I am not sure what's wrong. Here's the code.
#include "std_lib_facilities.h"
struct Name_pairs
{
vector<string>names;
vector<double>ages;
void quicksort(vector<string>& num, int top, int bottom);
void divide(vector<string>& array, int top, int bottom);
bool test();
string read_names();
double read_ages();
void print();
};
string Name_pairs::read_names()
{
string name;
cout << "Enter name: ";
cin >> name;
names.push_back(name);
return name;
}
double Name_pairs::read_ages()
{
double age;
cout << "Enter corresponding age: ";
cin >> age;
ages.push_back(age);
cout << endl;
return age;
}
int Name_pairs::divide(vector<string>& array, int top, int bottom)
{
string x = array[top];
int i = top-1;
int j = bottom-1;
string temp;
do{
do
{
j--;
} while(x>array[j]);
do
{
i++;
} while(x<array[i]);
if(i<j)
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
} while(i<j);
return j;
}
void Name_pairs::quicksort(vector<string>& num, int top, int bottom) // top is subscript of beginning of vector.
{
int middle;
if(top < bottom)
{
middle = divide(num, top, bottom);
quicksort(num, top, middle);
quicksort(num, middle+1, bottom);
}
return;
}
void Name_pairs::print()
{
for(int i = 0; i < (names.size()-1) && i < (ages.size()-1); ++i)
cout << names[i] << " , " << ages[i] << endl;
}
int main()
{
Name_pairs np;
vector<string>names;
vector<double>ages;
cout << "Enter names and ages. Use 0 to cancel.\n";
bool finished = false;
while(!finished){
finished = "0" == np.read_names();
finished = 0 == np.read_ages();
}
np.quicksort(names, 0, (names.size()-2));
np.print();
keep_window_open();
}
If you're trying to define additional vector variables within main, then the lines
np.vector<string>names; // error possibly here?
np.vector<double>ages;
Should be:
vector<string> names;
vector<double> ages;
You're redefining your struct members, or so it seems. But I don't see where you'd actually use those. Also, size() returns an unsigned variable of some sort, so you may need to cast it, or change the way you're comparing it to prevent compiler errors/warnings.
It's also worth noting, that if you want a couple more vectors declared within main() then it's good practice to name them something unique instead of having them share names with the struct members. Also, your main() doesn't have a return (needs to return int).
Get rid of the following lines in main() which are apparently causing your compiler to crash:
np.vector<string>names; // error possibly here?
np.vector<double>ages;
Then, a couple of your function definitions need to have their signatures changed:
int divide(vector<string>& array, int top, int bottom)
and
void quicksort(vector<string>& num, int top, int bottom)
need to change to
int Name_pairs::divide(vector<string>& array, int top, int bottom)
void Name_pairs::quicksort(vector<string>& num, int top, int bottom)
so they are seen as part of the Name_pairs struct instead of free functions.
I got it working. The final code: Pushes back data and sorts both in synchronization,
#include "std_lib_facilities.h"
struct Name_pairs
{
vector<string>names;
vector<double>ages;
void quicksort(vector<string>& num, vector<double>& num2, int top, int bottom);
int divide(vector<string>& array, vector<double>& array2, int top, int bottom);
bool test();
string read_names();
double read_ages();
void print();
};
string Name_pairs::read_names()
{
string name;
cout << "Enter name: ";
cin >> name;
names.push_back(name);
return name;
}
double Name_pairs::read_ages()
{
double age;
cout << "Enter corresponding age: ";
cin >> age;
ages.push_back(age);
cout << endl;
return age;
}
int Name_pairs::divide(vector<string>& array, vector<double>& array2, int top, int bottom)
{
string x = array[top];
int i = top-1;
int j = bottom+1;
string temp;
double temp2;
do{
do
{
j--;
} while(x<array[j]);
do
{
i++;
} while(x>array[i]);
if(i<j)
{
temp = array[i];
temp2 = array2[i];
array[i] = array[j];
array2[i] = array2[j];
array[j] = temp;
array2[j] = temp2;
}
} while(i<j);
return j;
}
void Name_pairs::quicksort(vector<string>& num, vector<double>& num2, int top, int bottom)
{
int middle;
if(top < bottom)
{
middle = divide(num, num2, top, bottom);
quicksort(num, num2, top, middle);
quicksort(num, num2, middle+1, bottom);
}
return;
}
void Name_pairs::print()
{
for (int i = 0; i < (names.size()-1) && i < (ages.size()-1); ++i)
cout << names[i] << " , " << ages[i] << endl;
}
int main(){
Name_pairs np;
cout << "Enter names and ages. Use 0 to cancel.\n";
bool finished = false;
while(!finished){
finished = "0" == np.read_names();
finished = 0 == np.read_ages();}
np.quicksort(np.names, np.ages, 0, (np.names.size()-2));
np.print();
keep_window_open();
}
(This was listed as an answer in the edits (to the original question) from the OP. It should have been posted as an answer, and I'm reposting it here.)
The following lines in main() should be deleted:
np.vector<string>names; // error possibly here?
np.vector<double>ages;
They already exist as part of instantiating Name_pairs.
Also, remove the parameter names from quicksort since it isn't really necessary and will make your code not function the way you think it should. The names you want to sort are members of Name_pairs. The ones you declared in main() are not the ones you read in with read_names().
EDIT: Actually, it might be easier for you if you declare a single vector with a struct that contains the age and name and sort that array. The entirety of your program implies that you want to sort the names and then print out each name with the associated age, but you only sort the name array.
EDIT2: And from the other answers, I think you need to learn more about how to declare member functions before you can fully solve this problem.
If you don't mind extra memory used but a little higher speed you could use a structure or pair in witch the int is the index in the second vector which you set before you sort.
Or if you don't actually need the vector operator[] and you can just iterate over the elements you could use a map.