How can I modify elements inside vectors? - c++

I'm trying to modify the elements inside a vector. After I change a certain block in an array and display it again, it won't show the new values but instead, retain the previous output. Am I doing it wrong?
////////////////////////////////////////////////////
// This displays the array/maze
////////////////////////////////////////////////////
void displayMaze( vector< vector<char> > &maze ) {
for( int i = 0; i < ROW; i++ ) {
for( int j = 0; j < COL; j++ ) {
cout << "[" << maze[ i ][ j ] << "] ";
}
cout << endl;
}
}
////////////////////////////////////////////////////
// This is where I change a certain element
////////////////////////////////////////////////////
void updateMouse( vector< vector<char> > maze, const int &mouse_row, const int &mouse_col ) {
for( int row = 0; row < ROW; row++ ){
for( int col = 0; col < COL; col++ ) {
if( ( row == mouse_row ) && ( col == mouse_col ) ) {
maze[ row ][ col ] = 'M';
break;
}
}
}
}

updateMouse takes the maze argument by value. Any changes it makes to the vector are made to the local copy within the function, which will be destroyed when the function exits. Change the function so that it takes the maze argument by reference.
void updateMouse( vector<vector<char>>& maze, const int &mouse_row, const int &mouse_col ) {
// ^^^
The updateMouse function can also be simplified to
void updateMouse( vector<vector<char>>& maze, int mouse_row, int mouse_col ) {
if(mouse_row < maze.size()) {
if(mouse_col < maze[mouse_row].size()) {
maze[mouse_row][mouse_col] = 'M';
}
}
}

You should be passing your vector as a reference (or pointer):
void updateMouse( vector< vector<char> > & maze, const int &mouse_row, const int &mouse_col ) {
Otherwise what you do is you change the copy of the maze

Related

2D Vector of Doubles editing causing crash

I am working on a C++ class that consists of a 2D Vector of Doubles. I am about to create the 2D Vector but when I try to edit the values inside of it, the program crashes. I have tried using the [][] operator and setting it equal to myDub and I have tried using a class like myMat.editSlot(i,j,myDub) and both have caused the program to crash.
//n == # of rows and cols (all matrices are square)
//infile opens the file properly
mat my_mat(n,n);
// Read input data
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(i,j,myDub);
}
}
and here is the class:
class mat
{
mat( int x , int y ) {
int row = x;
int col = y;
vector<vector<double>> A( row , vector<double>( row , 0 ) );
for ( int i = 0; i<row; i++ )
{
for ( int j = 0; j<col; j++ )
{
cout << setw( 6 ) << A[i][j];
}
cout << endl;
}
}
void editSlot( int x , int y , double val ) {
A[x][y] = val;
}
vector<vector<double>> A;
private:
int n;
};
It looks to me that the way you're initializing A is wrong. Try something like this:
A = vector<vector<double>>( row , vector<double>( row , 0 ) );
Another thing to consider both the constructor and the edit function aren't declared public.
Main problem that leads to crush is that you change size of a temporal vector A in your constructor while A vector that you declared as a field in your class object is not touched.
I suggest doing something like this:
mat(int x,int y) : A(y,vector<double>(x,0)) {
int row = x;
int col = y;
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
cout<<setw(6)<<A[i][j];
}
cout<<endl;
}
}
}
In this case you won't hide your A field in class with temporal A object in constructor function.
Also please pay attention not to swap x and y in your functions. For example, you have an error in your editSlot function:
void editSlot( int x , int y , double val ) {
A[x][y] = val;
}
, it should be:
A[y][x] = val;
according to constructor.

Vector Merge Algorithm C++

Having a hard time designing an efficient algorithm that accomplishes the following. If I start with a 2d vector A,
A = [1 2 3;
2 3 4;
5 6]
I want to take the rows that contain common elements and combine them (removing duplicates) resulting in 2d vector B:
B = [1 2 3 4;
5 6]
I can accomplish this in Matlab, but am having a hard time in C++. Any help is appreciated.
Try this, it worked for me with your example matrix. It looks like a lot of code, but there are functions just for the example and for debugging purpose.
void disp( const std::vector< int >& a )
{
for ( const auto item : a )
{
std::cout << item;
}
std::cout << "\n";
}
void disp( const std::vector< std::vector< int > >& matrix )
{
for ( const auto& row : matrix )
{
disp( row );
}
}
// I think there shall be some easier way for this.
bool hasCommonElements( const std::vector< int >& aVector1, const std::vector< int >& aVector2 )
{
for ( const auto item1 : aVector1 )
{
for ( const auto item2 : aVector2 )
{
if ( item1 == item2 )
{
return true;
}
}
}
return false;
}
void makeAllElementsUnique( std::vector< int >& aRow )
{
std::sort( aRow.begin(), aRow.end() );
aRow.erase( std::unique( aRow.begin(), aRow.end() ), aRow.end() );
}
void mergeRowsWithCommonValues( std::vector< std::vector< int > >& aMatrix )
{
for ( auto it = aMatrix.begin(); it != aMatrix.end(); ++it )
{
auto it2 = it + 1;
while ( it2 != aMatrix.end() )
{
if ( hasCommonElements( *it, *it2 ) )
{
(*it).insert( (*it).end(), (*it2).begin(), (*it2).end() ); // Merge the rows with the common value(s).
makeAllElementsUnique( (*it) );
it2 = aMatrix.erase( it2 ); // Remove the merged row.
}
else
{
++it2;
}
}
}
}
void example()
{
std::vector< std::vector< int > > matrix;
matrix.push_back( { 1, 2, 3 } );
matrix.push_back( { 2, 3, 4 } );
matrix.push_back( { 5, 6 } );
disp( matrix );
mergeRowsWithCommonValues( matrix );
disp( matrix );
}
Here is my own attempt, kinda messy, I know.
int index2 = 0;
int rowIndex = 0;
int tracker = 0;
int insert = 0;
// Loop over all rows
while (index2 < A.size()){
// Check if vector is empty. If so, copy the first row in.
if (B.empty()){
B.push_back(A[index2]);
index2++;
cout<<"Hit an empty.\n";
}
// If vector not empty, do the complicated stuff.
else if (!B.empty()){
for (int i = 0; i < A[index2].size(); i++){ // element in A
for (int j = 0; j < B.size(); j++){ // row in B
for (int k = 0; k < B[j].size(); k++){ // element in row in B
if (A[index2][i] == B[j][k]){
rowIndex = j;
tracker = 1;
}
}
}
}
// If tracker activated, we know there's a common element.
if (tracker == 1){
cout<<"Hit a positive tracker.\n";
for (int i = 0; i < A[index2].size(); i++){ // element in A
for (int j = 0; j < B[rowIndex].size(); j++){ // element in B at rowIndex
if (A[index2][i] != B[rowIndex][j])
insert++;
cout<<"Hit an insert increment.\n";
}
if (insert == B[rowIndex].size()){
cout<<"Hit an insert.\n";
B[rowIndex].push_back(A[index2][i]);
}
insert = 0;
}
index2++;
}else{
B.push_back(A[index2]);
index2++;
cout<<"Hit a zero tracker.\n";
}
}
tracker = 0;
}

C++: Pass two-dimensional array to function

This is probably so simple, but I can't figure out why this won't compile.
void display(int);
const int rows = 2;
const int cols = 2;
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
void display(const int ray[][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
invalid conversion from ‘int (*)[2]’ to ‘int’ [-fpermissive]|
This code will work
const int rows = 2;
const int cols = 2;
void display( const int ray[][cols]);
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
void display( const int ray[][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
Your function definition and function declaration do not match, one of them is of type int while the other is type void
Your function declaration is
void display(int);
and the definition is
int display(const int ray[0][cols])
and
int display(const int ray[0][cols])
^
0 ?
I think I see the problem here
The prototype is wrong. If you want a 2D array arg, it's more like this
int display(const int ray**);
The forward declaration of display is wrong. Either fix forward declaration or change order of functions:
#include <iostream>
using namespace std;
const int rows = 2;
const int cols = 2;
int display(const int ray[0][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
Live Example
Since you use global variables anyway, the easy thing is to change your declaration of display:
Declare display like this:
void display(int** array)
{...}
In this case you will actually be able to send your 2D array to the function because the type will match. A 2D array is an array of arrays and an array is just a pointer associated with some memory.
I am not giving the appropriate answer to this question. But an alternative.
As C++ suggests to use std::string inplace of char* . It also suggests to use vectors instead of array wherever applicable.
#include <iostream>
#include <vector>
void display( std::vector<std::vector<int>> );
int main()
{
std::vector<std::vector<int>> int_vec{ { 1 , 2 } , { 3 , 4 } };
display( int_vec );
system("PAUSE");
return EXIT_SUCCESS;
}
void display( std::vector<std::vector<int>> integer_vector )
{
for( auto& i : integer_vector )
{
for( auto& j : i )
{
std::cout << j << std::endl;
}
}
}
The global variables as rows and cols are gone :).

Dynamic Nested Loops (C++)

Hello I am looking for a way to write this C++ Code in a general way, so that if a want 20 columns I will not have to write 20 for loops:
for(int i=1; i<6; i++) {
for(int j=i; j<6; j++) {
for(int k=j; k<6; k++) {
for(int m=k; m<6; m++) {
std::cout << i << j << k << m << std::endl;
}
}
}
}
It is important that my numbers follow a >= Order.
I am very grateful for any help.
This recursive function should work:
#include <iostream>
bool inc( int *indexes, int limit, int n )
{
if( ++indexes[n] < limit )
return true;
if( n == 0 ) return false;
if( inc( indexes, limit, n-1 ) ) {
indexes[n] = indexes[n-1];
return true;
}
return false;
}
int main()
{
const size_t N=3;
int indexes[N];
for( size_t i = 0; i < N; ++i ) indexes[i] = 1;
do {
for( size_t i = 0; i < N; ++i ) std::cout << indexes[i] << ' ';
std::cout << std::endl;
} while( inc( indexes, 6, N-1 ) );
return 0;
}
live example
The design here is simple. We take a std::vector each containing a dimension count and a std::vector containing a current index at each dimension.
advance advances the current bundle of dimension indexes by amt (default 1).
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
return;
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which gives us an advance function for generic n dimensional coordinates.
Next, a filter that tests the restriction you want:
bool vector_ascending( std::vector<size_t> const& v ) {
for (size_t i = 1; (i < v.size()); ++i) {
if (v[i-1] < v[i]) {
return false;
}
}
return true;
}
then a for loop that uses the above:
void print_a_lot( std::vector<size_t> counts ) {
for( std::vector<size_t> v(counts.size()); v < counts; advance(v,counts)) {
// check validity
if (!vector_ascending(v))
continue;
for (size_t x : v)
std::cout << (x+1);
std::cout << std::endl;
}
}
live example.
No recursion needed.
The downside to the above is that it generates 6^20 elements, and then filters. We don't want to make that many elements.
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
{
size_t min = indexes[i];
// enforce <= ordering:
for (size_t j = i+i; j < counts.size(); ++j) {
if (indexes[j]<min)
indexes[j]=min;
else
break; // other elements already follow <= transitively
}
assert(vector_ascending(indexes));
return;
}
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which should do it without the vector_ascending check in the previous version. (I left the assert in to do testing).
This function works for me, but do not call it with 20 if you want it to finish.
#include <list>
#include <iostream>
std::list<std::list<int>> fun (std::list<std::list<int>> inputlist, int counter)
{
if(counter == 0)
{
return inputlist;
}
else
{
std::list<std::list<int>> outputlist;
for(std::list<int> oldlist : inputlist)
{
for(int i = 1; i<6; i++)
{
std::list<int> newlist = oldlist;
newlist.push_back(i);
outputlist.push_back(newlist);
}
}
return fun(outputlist, counter - 1);
}
}
int main()
{
std::list<int> somelist;
std::list<std::list<int>> listlist;
listlist.push_back(somelist);
std::list<std::list<int>> manynumbers = fun (listlist,5);
for (std::list<int> somenumbers : manynumbers)
{
for(int k : somenumbers)
{
std::cout<<k;
}
std::cout<<std::endl;
}
return 0;
}
Same with Processing (java) here :
void loopFunction(int targetLevel, int actualLevel, int min, int max, String prefix){
/*
targetLevel is the wanted level (20 in your case)
actualLevel starts from 1
min starts from 1
max is the max number displayed (6 in your case)
prefix starts from blank
see usage bellow (in setup function)
*/
for(int m=min; m<max; m++) {
if(targetLevel==actualLevel)
{
println(prefix+ " " + m);
}
else
{
loopFunction(targetLevel, actualLevel+1,m,max,prefix+ " " + m);
}
}
}
void setup(){
loopFunction(10,1,1,6,"");
}
Well, I am not the fastest in writing answer... when I started there was no other answer. Anyhow, here is my version:
#include <iostream>
#include <vector>
using namespace std;
class Multiindex {
public:
typedef std::vector<int> Index;
Multiindex(int dims,int size) :
dims(dims),size(size),index(Index(dims,0)){}
void next(){
int j=dims-1;
while (nextAt(j) && j >= 0){j--;}
}
Index index;
bool hasNext(){return !(index[0]==size-1);}
private:
bool nextAt(int j){
index[j] = index[j]+1;
bool overflow = (index[j]==size);
if (!overflow && j < dims-1){std::fill(index.begin() + j + 1,index.end(),index[j]);}
return overflow;
}
int dims;
int size;
};
int main() {
Multiindex m(4,6);
while (m.hasNext()){
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
m.next();
}
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
return 0;
}

C Bubble Sort: Sorted array loses biggest data piece and is replaced by a memory address [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Output I'm getting:
The base array
7290 5184 6174 8003 7427 2245 6522 6669 8939 4814 The
Sorted array
-33686019 2245 4814 5184 6174 6522 6669 7290 7427 8003
Press any key to continue . . .
I have no idea where this, -33686019, number is coming from. I've posted all of the code because I really don't know what could be causing it.
The Bubble Sort:
#include "Sorting.h"
double Sorting::bubbleSort( int size )
{
//Make a copy of our "master key" array for us to sort
int *toSort = whichArray(size);
int *theArray = copyArray( toSort, size );
double time;
cout << "The base array" << endl;
for(int i = 0; i < 10; i++ )
{
cout << theArray[i] << endl;
}
//The sort
//Begin time
timer.startClock();
bool swapped = true;
int temp = 0;
while( swapped == true )
{
swapped = false;
for( int i = 0; i < size; i++ )
{
if( theArray[i+1] < theArray[i] )
{
/*temp = theArray[i+1];
theArray[i+1] = theArray[i];
theArray[i] = temp;*/
swap(theArray[i + 1], theArray[i]);
swapped = true;
}
}
}
time = timer.getTime();
cout << "The Sorted array" << endl;
for(int x = 0; x < 10; x++ )
{
cout << theArray[x] << endl;
}
return time;
}
The Sorting Class:
#ifndef SORTING_H
#define SORTING_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//^For random numbers
#include <iostream>
#include "TimerSystem.h"
#include <iomanip>
using namespace std;
class Sorting
{
private:
//The below pointers will point to arrays that hold the data sets
int *n10;
int *n100;
int *n1000;
int *n10000;
TimerSystem timer;
double runs[4][4];
public:
Sorting();
~Sorting(){};
//Testing functions
void printArray();
void print2DArray();
void dryRun();
//Data manging and creating
int randomNumGen();
int* arrayGen( int size );//Returning a pointer
int* copyArray( int *toCopy, int size );//Makes an array that the program can sort. The leaves the original array intact
int* whichArray( int size );
void datasetRun( int whichSort );//Does three runs of a sort and gets the average for all 4 array sizes
//Sorts
double bubbleSort( int size );
};
#endif
Other Called Functions:
#include "Sorting.h"
int Sorting::randomNumGen()
{
int randomNumber = rand() % 10000 + 1;
if( randomNumber > 10000 || randomNumber < 0 )
{
system("pause");
}
return randomNumber;
}
int* Sorting::arrayGen( int size )
{
int *theArray= new int[size];
for( int i = 0; i < size; i++ )
{
theArray[i] = randomNumGen();
}
return theArray;
}
int* Sorting::copyArray( int *toCopy, int size )
{
int *newArray = new int[size];
for( int i = 0; i < size; i++ )
{
newArray[i] = toCopy[i];
}
return newArray;
}
int* Sorting::whichArray( int size )
{
if( size == 10 )
{
return n10;
}
else if( size == 100 )
{
return n100;
}
else if( size == 1000 )
{
return n100;
}
else if( size == 10000 )
{
return n1000;
}
return NULL;
}
void Sorting::datasetRun( int whichSort )
{
//1: Bubble
//2: Insertion
//3: Selection
//4: Shell
//5: Quick
//6: Merge
int col = 0;
int row = 0;
int set = 10;
bool runDone = false;
if( whichSort == 1 )
{
for( int row = 0; row < 4; row++ )
{
for( int col = 0; col < 4; col++ )
{
runs[row][col] = bubbleSort( set );
}
//set = set * 10;
}
}
}
//Constructor
Sorting::Sorting()
{
//For the random number generator
srand( time(NULL) );
n10 = arrayGen( 10 );
n100 = arrayGen( 100 );
n1000 = arrayGen( 1000 );
n10000 = arrayGen( 10000 );
}
//Functions for testing
void Sorting::printArray()
{
int size = 10000;
for( int i = 0; i < size; i++ )
{
cout << n10000[i] << " ";
}
}
void Sorting::print2DArray()
{
for( int height = 0; height < 4; height++ )
{
for( int width = 0; width < 4; width++ )
{
cout << runs[height][width] << endl;
}
cout << "\n\n";
}
}
The Main Function:
#include "Sorting.h"
void main()
{
//Makes the numbers easily readable
cout.setf(ios::fixed | ios::showpoint);
cout.precision(16);
Sorting theSorting;
//theSorting.printArray();
//cout << theSorting.bubbleSort( 10 ) << endl;
//theSorting.datasetRun(1);
//theSorting.print2DArray();
theSorting.bubbleSort( 10 );
system("pause");
}
The following bit is not correct:
for( int i = 0; i < size; i++ )
{
if( theArray[i+1] < theArray[i] )
It is accessing one beyond the boundary of the array. The for loop should probably be:
for( int i = 0; i < size - 1; i++ )
Look at this:
for( int i = 0; i < size; i++ )
{
if( theArray[i+1] < theArray[i] )
theArray[i+1] is undefined on the last iteration of the loop.
Change the loop's continuation expression from i < size to i < (size-1)