why is vector subscript out of range - c++

I have a vector full of monster objects which are initialized onto a 10X10 map which works. I am now playing with some code to prevent monsters being spawned on the same map co-ordinate. when i run the code it cuts and brings up "vector subscript out of range" and i have no idea why. Any help would be great.
main function
#include "stdafx.h"
#include "character.h"
#include "monster.h"
#include "player.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
using namespace std;
vector<monster*> monVec;
vector<int> monx;
vector<int> mony;
player player1;
bool collision();
void initialise();
int main(){
initialise();
player1.moveChar(3, 6);
bool temp;
temp = collision();
system("pause");
return 0;
}
initialize function
void initialize()
{
srand(time(NULL));
for (int n = 0; n < 10; n++)
{
int inx = rand() % 9;
int iny = rand() % 9;
if (n == 0){
monx.push_back(inx);
mony.push_back(iny);
}
for (int i = 0; i < n; i++)
{
-------->if (inx != monx[i] && iny != mony[i]){
monx.push_back(inx);
mony.push_back(iny);
}
else n--;
}
monVec.push_back(new monster());
monVec[n]->moveChar(inx, iny);
cout << endl << inx << ", " << iny << endl;
}
}
cout is just to check if its working once it runs and arrow indicates problem line.
thanks

In your initialize
you do the following
<for 10 times>
<when first time, add one item to the x,y vectors>
<access the up to 10nth element of the x,y vectors> //But vectors are only guaranteed to have at least one element each
<maybe add one item to the x,y vectors>
Problem is already that there is a path where there are not enough elements in your vectors. Plus the mistake about assignment and comparison in your if like #Michael Waltz already mentioned.

void initialize()
{
srand(time(NULL));
for (int n = 0; n < 10; n++)
{
int inx = rand() % 9;
int iny = rand() % 9;
if (n = 0){ //<<--------------------------- replace (n = 0) by (n == 0)
monx.push_back(inx);
mony.push_back(iny);
}
for (int i = 0; i < 10; i++)
{
// <<<< here monx and mony may contain only
// one element so monx[1] and mony[1] are invalid
if (inx != monx[i] && iny != mony[i]){
monx.push_back(inx);
mony.push_back(iny);
}
else n--;
}
monVec.push_back(new monster());
monVec[n]->moveChar(inx, iny);
cout << endl << inx << ", " << iny << endl;
}
}

Related

Is there a way to pass a vector from a helper function to another helper function in C++?

I'm working through one of the classic C++ exercises of writing a program to determine which numbers are primes. The version I'm working on now requires me to be able to determine which values are prime up to a value inputted by the user called max.
The algorithm I'm attempting to construct behaves in the following fashion:
1) Enter the desired max value.
2) Take this max and then put it into a function which will calculate the sqrt(max).
3) Using sqrt(max) I will construct a vector of the primes up to the value of sqrt(max)
4) using this sqrt(max) vector I will then evaluate which values are prime up to the value max by creating a specific function to determine what values in the list up to max are prime. Then I will generate a list of all these primes.
With this being the structure here is my code for the endeavor:
#include "pch.h"
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
using std::cin;
using std::cout;
using std::string;
using std::vector;
int determine_prime(int x) {
// function made to determine if a number is prime
// used the fact that to determine if number is prime only need to check if
// prime values less than sqrt(x) divide x
vector<int> vector_of_sqrt_primes = list_of_prime_sqrt();
vp_1 = x % vp_1 = x % vector_of_sqrt_primes[i];
for (int i = 0; i < vector_of_sqrt_primes.size(); i = i + 1) {
if (vp_1 == 0 &&
x != vector_of_sqrt_primes[i]) { // verifying if value is prime
cout << x << " is not a prime number. \n";
return 0;
}
else {
cout << x << " is a prime number. \n";
return 1;
}
}
}
int list_of_prime_sqrt(int y) {
// using this vector as reference for all values less than the sqrt of max
vector<int> vector_of_primes_sqrt = {2};
int vps = 0;
for (int i = 2; i < round(sqrt(y)); i = i + 1) {
for (int j = 0; j < vector_of_primes_sqrt.size(); j = j + 1) {
vps = i % vector_of_primes_sqrt[j];
if (vps == 0 && i != vector_of_primes_sqrt[j]) {
cout << i << " is not a prime number. \n";
} else {
cout << i << " is a prime number. \n";
vector_of_primes_sqrt.push_back(i);
}
}
}
}
int main() {
int max = 0;
vector<int> primes_list = {};
cout << "Please enter the number of integers you would like to inspect "
"whether they are prime.\n";
cin >> max;
list_of_prime_sqrt(max);
for (int i = 1; i < max + 1; i = i + 1) {
int p = determine_prime(i);
if (p == 1) {
primes_list.push_back(i);
}
}
for (int j = 0; j < primes_list.size(); j = j + 1) {
cout << primes_list[j] << "\n";
}
}
So what I was hoping was that I would be able to use vector_of_sqrt_primes in the determine_prime() function and then work out which values are primes a return them to my main(). But I am hitting a wall. So all of this to askif there is a way for me to be able to do this? I haven't gotten to the point to be able to use pointers or anything advanced. I'm working through Stroustroup Programming Principles and Practices and this is Chapter 4.
Below are two different ways in solving your problem. One returns a vector and the other uses pass by reference to be able to modify the vector passed into the parameter
#include <iostream>
#include <vector>
#include <string>
bool is_prime(int number){
//exceptions
if(number == 1) return false;
if(number == 2 || number == 5) return true;
std::string str = std::to_string(number);
if(str.back() == '1' || str.back() == '3' || str.back() == '7' || str.back() == '9'){
for(int i = 3; i * i <= number; i++){
if(number % i == 0){
return false;
}
}
return true;
}
return false;
}
//adds the value to the vector passed in and the values will 'save'
void find_primes(std::vector<int>& primes, int max){
for(int i = 0; i < max; i++){
if(is_prime(i)) primes.push_back(i);
}
}
//adds the results to a vector and returns that vector
std::vector<int> return_vec_primes(int max){
std::vector<int> results;
for(int i = 0; i < max; i++){
if(is_prime(i)) results.push_back(i);
}
return results;
}
int main(){
std::vector<int> reference_vec;
//pass the vector into the function
find_primes(reference_vec, 100);
//the function will return the vector into 'returned_vec'
std::vector<int> returned_vec = return_vec_primes(100);
//same results
for(int i : reference_vec) std::cout << "prime: " << i << "\n";
for(int i : returned_vec) std::cout << "prime: " << i << "\n";
return 0;
}

least number of digits without duplicates

I am a C++ noob. I have a list of numbers that I put into a Vector. All numbers are 9 digit integers and are unique. I want to know what is the least amount of digits (starting from the right) that can be used to uniquily identify each number in the set. right now there are only 6 numbers, but the list could potentially grow into the thousands. I have posted my code thus far (not working.)
EDIT output is the following...
digit is 1
digit is 1
digit is 1
RUN FINISHED; exit value 0; real time: 0ms; user: 0ms; system: 0ms
This is mostly a learning exercise. Please be generous and explicit with your comments and solutions.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <algorithm>
using namespace std;
int main() {
//declare stream variable and load vector with values
ifstream myfile("mydata.txt");
vector<int> myVector;
int num;
while (myfile >> num) {
myVector.push_back(num);
}
//sort and squack if there is a duplicate.
std::sort(myVector.begin(), myVector.end());
for (int i = 0; i < (myVector.size() - 1); i++) {
if (myVector.at(i) == myVector.at(i + 1)) {
printf("There are duplicate student numbers in the file");
exit(EXIT_FAILURE);
}
}
//if it get here, then there are no duplicates of student numbers
vector<int> newv;
int k = 1;
bool numberFound = false;
bool myflag = false;
while (numberFound == false) {
//loop through original numbers list and add a digit to newv.
for (int j = 0; j < myVector.size(); ++j) {
newv.push_back(myVector.at(j) % (10^k));
}
sort(newv.begin(), newv.end());
for (int i = 0; i < (newv.size() - 1); i++) {
if (newv.at(i) == newv.at(i + 1)) {
//there is a duplicate for this digit. Set flag.
myflag = true;
}
if (myflag == false) {
numberFound = true;
cout << "digit is " << k << endl;
} else {
k++;
}
}
}
// for (int i = 0; i < myVector.size(); i++) {
// cout << "||" << myVector.at(i) << "||" << endl;
// }
//
// for (int i = 0; i < newv.size(); i++) {
// cout << "---" << newv.at(i) << "---" << endl;
// }
return 0;
}
Check the below code.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <math.h>
using namespace std;
int main() {
//declare stream variable and load vector with values
ifstream myfile("mydata.txt");
vector<int> myVector;
int num;
while (myfile >> num) {
myVector.push_back(num);
}
//sort and squack if there is a duplicate.
std::sort(myVector.begin(), myVector.end());
for (int i = 0; i < (myVector.size() - 1); i++) {
if (myVector.at(i) == myVector.at(i + 1)) {
printf("There are duplicate student numbers in the file");
exit(EXIT_FAILURE);
}
}
//if it get here, then there are no duplicates of student numbers
vector<int> newv;
int k = 1;
bool numberFound = false;
bool myflag = false;
int p = 1;
while (numberFound == false) {
//loop through original numbers list and add a digit to newv.
newv.clear();
p = p * 10;
for (int j = 0; j < myVector.size(); ++j) {
newv.push_back(myVector[j] % p);
}
sort(newv.begin(), newv.end());
myflag = false;
for (int i = 0; i < (newv.size() - 1); i++) {
if ( newv[i] == newv[i+1]) {
//there is a duplicate for this digit. Set flag.
myflag = true;
break;
}
}
if (myflag == true){
k ++;
}else{
numberFound = true;
cout << "digit is " << k << endl;
break;
}
}
return 0;
}
Sample Input:
123451789
123456687
125456789
123456780
Output:
digit is 4

Treating an array of bools as though incrementing in binary [duplicate]

This question already has answers here:
Bitset in C++, about continuously add
(2 answers)
Closed 8 years ago.
I'm trying to create a loop that changes the values in a boolean array so that it looks like the array is incrementing in binary values.
For example
1st iteration [0|0|0]
2nd iteration [0|0|1]
3rd iteration [0|1|0]
4th iteration [0|1|1]
etc.
This array is dynamic, however, and can be different sizes. So whatever loop I write would need to also work on an array with five elements instead of three.
Apologies for not having any starting code, but I've been frustrating myself with this for hours and still can't even come up with how to begin.
Try this. This may not be complete but you could do something similar
#include <iostream>
using namespace std;
void increment(bool* array, int len)
{
for (int i = len - 1; i >= 0; --i)
{
if ( ! array[i])
{
array[i] = true;
return;
}
array[i] = false;
}
}
int main()
{
bool* array = new bool[10];
for (int i = 0; i < 5; ++i)
{
increment(array, 10);
for (int i = 0; i < 10; ++i)
{
cout << (array[i] ? 1 : 0) << "|";
}
cout << endl;
}
return 0;
}
#include <iostream>
#include <cmath>
#include <memory>
using namespace std;
void ArrayIterate(int);
void printArray(bool*,int);
void ArrayIterate(int arraySize)
{
int decimal_value = 0;
int decimal_place_value = 0;
bool* boolArray = new bool(arraySize);
long double max_itr = pow(2,arraySize);
for (int i = 0; i < max_itr ; ++i)
{
decimal_value = i;
// set array values
for ( int k = arraySize - 1; k >= 0; --k)
{
decimal_place_value = pow(2,k);
if( decimal_value != 0 && decimal_value / decimal_place_value >= 1 )
{
boolArray[k] = true;
decimal_value -= decimal_place_value;
}
else
boolArray[k] = false;
}
printArray(boolArray,arraySize);
cout << " = " << i << endl; ;
}
delete boolArray;
return;
}
void printArray(bool* boolArray, int arraySize)
{
cout << "\t";
for(int i = arraySize - 1; i >= 0; --i)
cout << ((boolArray[i] == true)? 1 : 0) << " ";
return;
}
int main()
{
cout << "\n\n";
ArrayIterate(4);
cout << "\n\n" << endl;
return 0;
}

not declared in scope c++ [duplicate]

This question already has answers here:
'foo' was not declared in this scope c++
(3 answers)
Closed 6 years ago.
I am getting an error that breed is not declared in scope even though it is right below the fucntion. What is wrong?
The exact error is: prog.cpp: In function ‘void best(std::string*)’:
prog.cpp:131:15: error: ‘breed’ was not declared in this scope
breed(bestRats)
#include <iostream>
#include <sstream>
#include <vector>
#include <math.h>
#include <map>
#include <string.h>
#include <queue>
#include <regex>
#include <bitset>
#include <stdlib.h>
#include <climits>
// #include "dungeonrats.cpp"
using namespace std;
/*
Finds the maximum integer in an array of integers.
Size is the size of the given array.
*/
int getMax(int* numbers, int size) {
int maximum = INT_MIN;
for (int i = 0; i < size; i++) {
if (numbers[i] > maximum) maximum = numbers[i];
}
return maximum;
}
int getMaxi(int* numbers, int size) {
int maximum = INT_MIN;
int maxi;
for (int i = 0; i < size; i++) {
if (numbers[i] > maximum) {
maximum = numbers[i];
maxi = i;
}
}
return maxi;
}
/*
"randomly" generates a new maze (but is it REALLY random?)
aim is 65% empty tiles
10% food tiles
10% obstacles
15% pits
*/
string getNewMaze(string mapseed) {
string maze = mapseed.substr(6); // get everything except the 25:25:
for (int i = 0; i < 626; i++) {
int percentile = rand() % 100; // from 0 to 99
if (percentile < 65) {
maze[i] = '.';
}
else if (percentile >= 65 && percentile < 75) {
maze[i] = '$';
}
else if (percentile >= 75 && percentile < 85) {
maze[i] = '*';
}
else maze[i] = 'X';
}
return maze;
}
/*
A function used to print how many of each kind of tile
exist in the maze.
*/
void testFrequency(string mapseed) {
int numEmpty = 0;
int numFood = 0;
int numObs = 0;
int numPit = 0;
for (int i = 0; i < 626; i++) {
if (mapseed[i] == '.') {
numEmpty++;
}
if (mapseed[i] == '$') {
numFood++;
}
if (mapseed[i] == '*') {
numObs++;
}
if (mapseed[i] == 'X') {
numPit++;
}
}
cout << "Number of empty tiles is " << numEmpty << endl;
cout << "Number of food tiles is " << numFood << endl;
cout << "Number of obstacles is " << numObs << endl;
cout << "Number of pits is " << numPit << endl;
}
/*
Returns an array of size 2 containing the best two rats.
*/
void best(string r[]) {
// r is the array of five rat genomes
//int moves = simulator(mapseed, genome, start_row, start_col);
int* ratMoves = new int[5]; // array that stores how long each rat lasted
int maxIndex = 0;
int max = INT_MIN;
string originalMapseed = "25:25:..$.$.X.............X....$X.X*..X$..X...*X$..$...X$.$......X.$.X...XX.$.X*.*.*..X..X.**.......X..$$$...........XX.....................$...X...*.$..X..$X..........$.*..X.....$.X..$*.$X......$...X.*X$......$.**.X.X..XX$X..*....*..X.X....$...X...X........$.X....$...*...X$*........X..$*$$......$$...$*..X.$.$......$.$.$...$..X.*.....X..$......$.XX*..X.$.X......X$*.**.....X*...$..XX..X.....$....X....X...X....X.$X$..X..........$...*.X$..X...$*...........*....XXX$$.$.$..*$XX..XX..*.....$......X.XX$..$$..X$.XX.$$..X.*..*......X......$..$.$$..*...X.........$X....$X.$$.*.$.$.$..**.....X.$.$X.*.$.........$**..X.X.X$X.$.*X.X*..$*.";
for (int i = 0; i < 5; i++) {
string mapseed = getNewMaze(originalMapseed);
int sumTurns = 0;
for (int k = 0; k < 10; k++) {
string mapseed = getNewMaze(originalMapseed);
// sumTurns += simulator(mapseed,r[i],12,12); // uncomment this line once in correct file
}
ratMoves[i] = sumTurns / 10; // average of rat's performance
// over 10 random maps
if (ratMoves[i] > max) { // find the best
max = ratMoves[i];
maxIndex = i;
}
}
string bestRats[2];
bestRats[0] = r[maxIndex]; // store the best
ratMoves[maxIndex] = INT_MIN; // remove the best from array of rat moves
bestRats[1] = r[getMaxi(ratMoves, 5)]; // get the second best & store it
breed(bestRats);
}
void breed(string r[]) {
int cap = 10;
string c[5];
for (int j = 0; j<5; j++)
for (int i = 0; i<190; i++) {
int check = rand() % cap + 1;
if (check % 2 == 0) {
if (check == 0)
c[j] += rand() % 81 + 42;
else
c[j] += r[1][i];
}
else
c[j] += r[0][i];
}
best(c);
}
int main() {
string c[5];
for (int j = 0; j<5; j++)
for (int i = 0; i<190; i++)
c[j] += rand() % 81 + 42;
best(c);
}
Declare
void breed(string r[]);
on the top of file before first usage or include appropriate header file containing this declaration.
c++ checks for function names at the moment it reads them in the code (symbolically). if it hasn't read it yet, it doesn't know it exists. that's why you at least need to declare a function's prototype before using it in your code.
ergo, here you need to at least put
void breed(string r[]);
before using the function.
When the compiler processes your code, it starts at the top and goes to the end. At any given point in this process, it only "knows" about things it's already seen. So when you try to call the breed function from the best function, it doesn't know what you're talking about because it hasn't seen anything called breed yet.
To fix this, you need to let the compiler know what the breed function is before you attempt to use it. There are a few ways to do this. The easiest would be to move the entire breed function above the best function in your source file. An alternate would be to declare the breed function higher up in the file before defining it later. To declare it, simply include the line void breed (string r[]); somewhere (don't forget the ; at the end). This way the compiler knows that "breed" refers to a function that takes an array of strings and returns nothing, which is enough for it to compile calls to the function.

Quicksort in an array C++

I am trying to partition an array using a quicksort algorithm shown in the code. I believe the problem is in the while loop. Can you see/explain what I'm doing wrong and what I should do to fix it? Thanks!
Edited because I posted an earlier version of the code.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int intArray[10];
int sizeArray= 10;
int main(){
srand(time(0));
for(int i = 0; i < sizeArray; i++){
//random numbers from 1 to 10:
intArray[i] = rand() % 100 + 1;
}
for(int i = 0; i < sizeArray; i++){
cout << intArray[i] << " ";
}
int *pivot = &intArray[0];
int *first = &intArray[1];
int *last = &intArray[9];
cout<<"pivot "<<*pivot <<endl;
while(first<last)
{
while(*first<*pivot)
{
first++;
}
while(*last>*pivot)
{
last--;
}
if(*first>*last)
{
int aSwap = 0;
aSwap = *first;
*first = *last;
*last = aSwap;
}
if((first-1) > last)
break;
}
int bSwap=0;
bSwap = *first;
*first= *pivot;
*pivot = bSwap;
cout<<"After partition"<<endl;
for(int i = 0; i < sizeArray; i++){
cout << intArray[i] << " ";
}
}
I'll give you one immediate peice of advice re:
while(*first<*pivot)
If your pivot at array[0] is the largest value in the array, you're going to run off the end of the array and keep going, resulting in undefined behaviour.
The termination condition for that loop should include detecting if the first pointer has reached the last one.
Ditto for the loop that decrements last.
And, of course, once the pointers meet, there's no need to do a swap.
And your edit comparing the first against last values is actually worse. You're supposed to be looking for two values that you will swap across from where the pivot wiill eventually go.
I suggest reverting the code and simply adding the limiting check I suggested. Here is the correct code for doing the partition swapping operation, from some code I wrote not that long ago:
// Simplest form of pivot selection.
pvt = 0;
lft = 1;
rgt = 9;
// Continue until new pivot point found.
while (lft < rgt) {
// find value on left greater than pivot value.
while ((lft < rgt) && (array[lft] <= array[0]))
lft++;
// Then, assuming found, find value on right less than pivot value.
if (lft < rgt) {
while ((lft < rgt) && (array[rgt] >= array[0]))
rgt--;
// Swap them if found.
if (lft < rgt)
SWAP (array[lft], array[rgt]);
}
}
// Back up to find proper swap point for pivot value, then swap.
while ((lft > 0) && (array[lft] >= array[0]))
lft--;
if (lft != 0)
SWAP (array[lft], array[0]);
// Now everything left of pivot is less than pivot value, everything
// right is greater/equal. Go and sort the two sections.
You are making your life too complicated.
GCC 4.7.3: g++ -Wall -Wextra main.cpp
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int intArray[10];
int sizeArray= 10;
int main() {
srand(time(0));
for (int i = 0; i < sizeArray; ++i) {
//random numbers from 1 to 10:
intArray[i] = rand() % 100 + 1; }
for(int i = 0; i < sizeArray; ++i){
cout << intArray[i] << " "; }
int* pivot = &intArray[0];
cout << "pivot " << *pivot << endl;
for (int i = 0; i < sizeArray; ++i) {
if (intArray[i] < *pivot) {
std::swap(intArray[i], *(pivot + 1)); // move the pivot ahead one
std::swap(*pivot, *(pivot + 1)); // move the value into the hole
++pivot; }}
cout<<"After partition"<<endl;
for (int i = 0; i < sizeArray; i++){
cout << intArray[i] << " "; }
return 0; }