Passing into a function a part of my matrix (2d array) - c++

In my program im trying to add the values of a sub-part of my 2d array, a small box of 3 by 3 from a 9 by 9 matrix. Im choosing that small box by the % of rows and columns by 3(modulus 3). (meaning it will take cells like [0][0], [0][3], and so on )
which i want those to be my top right corner of the box and then add 2 more rows and columns making it for instance if we started at [0][0] we will add [0-2][0-2] (3 by 3 box). Im calculating that through a function (as a practice to use functions). The problem is that the program seems to only take in the value of the first cell from that small box, and when i try to loop on the rest of that small box, and add their values, it doesnt take the values correctly (or at all)
i want to know if my parameters are wrong, or im giving the function wrong parameters.
any help would be appreciated.
//------------including section-----------
#include <iostream>
#include <cstdlib>
//------------using section---------------
using std::cin;
using std::cout;
using std::endl;
//-----our constants and variables---------
const int N=3; //initializing our rows and cols as constants
int counter=0, arr[N*N][N*N];
int sumofrow=0, sumofcol=0,sumsquare=0;
//-------prototypes----------------
void READ_MATRIX(int arr[][N*N]);
bool issquare(int arr[][N*N],int row, int col);
//-------main-------------
int main()
{
//calling on the function to input our matrix
READ_MATRIX(arr);
//checking what functions returned
if(counter==0)
cout<<1;
else
cout <<0;
return EXIT_SUCCESS;
}
//-----functions--------
//----readmatrix------
void READ_MATRIX(int arr[][N*N])
{
for (int row=0; row<N*N; row++)
for (int col=0; col<N*N; col++) {
cin >> arr[row][col];
if (row%3==0&&col%3==0)
issquare(arr, row, col);
}
}
//---------issquare-------------
bool issquare(int arr[][N*N],int row, int col)
{
sumsquare=0;
for (int r=0;r<3;r++) //trying to loop on values of array
for (int c=0;c<3;c++)//trying to loop {
//r+row(because row is passed into the function at 0,3,6)
//same for col.
sumsquare+=arr[r+row][c+col]; // this is where it goes wrong
}
//checking to see if sum reached a certain value..
if (sumsquare==45)
return true;
else {
counter++;
return false;
}
}

You are adding values before you accept them. For example, when row = 0 and col = 0 in function READ_MATRIX(), you call issquare() before all values under that 3x3 box are accepted. In case you have initialized all values to zero, the only value contributing to your sum is the first value i.e. arr[0][0].
What you need to do is trigger issquare() function for row = 2,4,8 and col = 2,4,8. Inside the function issquare(), index the array as arr[row-r][col-c].

The error is that issquare() is called before the values it uses have been assigned/read. At the call to issquare(), of all values used in that function, only arr[row][col] is known yet.
What you have to do is to first read the data completely, and only then look at their properties.

Your function issquared is getting called on the first element of your array.
>>> 0 % 3
0
So you are trying to access values outside of your array. CLARIFICATION: They are not initialised yet so they do not belong to your array just yet (this is an over-simplification, the issue is related to memory allocation which I don't know if you have started yet)
Change the line:
if (row%3==0&&col%3==0)
To:
if ((row != 0 && col != 0) && (row%3 == 0 && col%3 == 0))
Also I'd suggested doing a similar check for the last element just to make sure your smaller box is within the boundaries of your matrix.

Related

Placing a piece in a connect four game using c++

Ok so i have a homework assignment and i dont know where to start with this function.
bool placePiece(char** pBoard, int colSize, int rowSize, int columnSelection, char player)
The function is to place a piece represented by char player, on the game board char** pBoard (a 2dArray made from colSize and rowSize) the function is to put the players piece at the bottom of the column selected during that players turn. also if a piece is already at the bottom of the column it puts the piece on top of that one and if the column is full it will return false.
really the biggest issue im having is i really dont understand how im supposed to be using pBoard.
Im not looking for someone to do it for me but just to help me start out on the right path.
To solve this, you need to understand arrays and loops. The first argument in your signature is an array containing your board data (and the next two arguments the dimensions of it) - there you need to access the first element at the columnSelection position and set it to the value of the player argument. The return value should indicate if the operation was successful.
bool placePiece(char** pBoard, int colSize, int rowSize, int columnSelection, char player) {
if (columnSelection >= colSize) {
/* invalid column */
return false;
}
for (size_t i = 0; i < rowSize; ++i) {
/* loop to go over all rows - starting with 0 */
if (pBoard[columnSelection][i] == 0) {
/* find first empty row and set it to 'player' value */
pBoard[columnSelection][i] = player;
return true;
}
}
/* no free row found -> all rows already set*/
return false;
}
This code assumes an column-row order in your array and goes from row 0 upwards, but you should get the general idea.

Assigning a structure to another structure results in garbage

The two structures used in my code, one is nested
struct Class
{
std::string name;
int units;
char grade;
};
struct Student
{
std::string name;
int id;
int num;
double gpa;
Class classes[20];
};
I am trying to figure out a way to sort the structures within the all_students[100] array in order of their ID's in ascending order. My thought was, to start counting at position 1 and then compare that to the previous element. If it was smaller than the previous element then I would have a temporary array of type Student to equate it to, then it would be a simple matter of switching them places within the all_students array. However, when I print the results, one of the elements ends up being garbage numbers, and not in order. This is for an intermediate C++ class in University and we are not allowed to use pointers or vectors since he has not taught us this yet. Anything not clear feel free to ask me.
The function to sort the structures based on ID
void sort_id(Student all_students[100], const int SIZE)
{
Student temporary[1];
int counter = 1;
while (counter < SIZE + 1)
{
if (all_students[counter].id < all_students[counter - 1].id)
{
temporary[0] = all_students[counter];
all_students[counter] = all_students[counter - 1];
all_students[counter - 1] = temporary[0];
counter = 1;
}
counter++;
}
display(all_students, SIZE);
}
There are a few things wrong with your code:
You don't need to create an array of size 1 to use as a temporary variable.
Your counter will range from 1 to 100, you will go out of bounds: the indices of an array of size 100 range from 0 to 99.
The following solution uses insertion sort to sort the array of students, it provides a faster alternative to your sorting algorithm. Note that insertion sort is only good for sufficiently small or nearly sorted arrays.
void sort_id(Student* all_students, int size)
{
Student temporary;
int i = 1;
while(i < size) // Read my note below.
{
temporary = all_students[i];
int j = i - 1;
while(j >= 0 && temporary.id < all_students[j].id)
{
all_students[j+1] = all_students[j]
j--;
}
all_students[j+1] = temporary;
i++;
}
display(all_students, size);
}
Note: the outer while-loop can also be done with a for-loop like this:
for(int i = 1; i < size; i++)
{
// rest of the code ...
}
Usually, a for-loop is used when you know beforehand how many iterations will be done. In this case, we know the outer loop will iterate from 0 to size - 1. The inner loop is a while-loop because we don't know when it will stop.
Your array of Students ranges from 0, 99. Counter is allowed to go from 1 to 100.
I'm assuming SIZE is 100 (in which case, you probably should have the array count also be SIZE instead of hard-coding in 100, if that wasn't just an artifact of typing the example for us).
You can do the while loop either way, either
while(counter < SIZE)
and start counter on 0, or
while (counter < SIZE+1)
and start counter on 1, but if you do the latter, you need to subtract 1 from your array subscripts. I believe that's why the norm (based on my observations) is to start at 0.
EDIT: I wasn't the downvoter! Also, just another quick comment, there's really no reason to have your temporary be an array. Just have
Student temporary;
I overlooked the fact that I was allowing the loop to access one more element than the array actually held. That's why I was getting garbage because the loop was accessing data that didn't exist.
I fixed this by changing while (counter < SIZE + 1)
to: while (counter < SIZE )
Then to fix the second problem which was about sorting, I needed to make sure that the loop started again from the beginning after a switch, in case it needed to switch again with a lower element. So I wrote continue; after counter = 1

C++ Function will not execute more than once

I've tried looking around but I can't find anything about this anywhere.
I'm writing a custom array class with a "push" function to add a value to the array.
It seems to work perfectly fine but won't execute more than once.
Take the main method below for example:
int main()
{
Array<int> test(4,5);
test.push(4);
test.writeOrdered("Output.txt");
return 0;
}
This will put the int value 4 into the array at the first available position and execute the writeOrdered function.
The following main method, on the other hand:
int main()
{
Array<int> test(4,5);
test.push(4);
test.push(5);
test.writeOrdered("Output.txt");
return 0;
}
This will put the number 4 into the array at the first available point as above and then stop. It won't execute any further lines of code.
Here's the push function for reference:
void push(Datatype p_item)
{
bool inserted = false;
int i = 0;
while (inserted == false)
{
if (m_array[i] < 0)
{
m_array[i] = p_item;
i++;
inserted = true;
cout << p_item << " saved to array" << endl;
system("pause");
}
}
}
You have an infinite loop. After the first insert m_array[0] >= 0 and i never grows. You would have found it out, had you debugged the code somehow.
Basically I don't understand your push function but the way it is, after you insert a non-negative value into the first position any further call to your push function results in a tight loop.
I imagine that you want the i++ outside the if statement.
Without seeing the full implementation of the Array class I would guess that the array m_array contains negative numbers by default. This will allow the first call to the push method to succeed. The next call to the method contains a value of 4 at index 0 and will be stuck in an infinite loop because inserted will never be set to true nor will the value of i be incremented.

How to determine the number of array 100 are not equal to each other

I am coding a Sudoku program. I found the number in the array determine whether duplicate each other is hard.
Now I have an array: int streamNum[SIZE]
if SIZE=3,I can handle this problem like:if(streamNum[0]!=streamNum[1])...
if SIZE=100,I think that I need a better solution, is there any standard practice?
There are a couple of different ways to do this, I suppose the easiest is to write two loops
bool has_duplicate = false;
for (int i = 0; i < SIZE && !has_duplicate; ++i)
for (int j = i + 1; j < SIZE && !has_duplicate; ++j)
if (streamNum[i] == streamNum[j])
has_duplicate = true;
if (has_duplicate)
{
...
}
else
{
...
}
The first loop goes through each element in the array, the second loop checks if there is a duplicate in the remaining elements of the array (that's why it starts at i + 1). Both loops quit as soon as you find a duplicate (that's what && !has_duplicate does).
This is not the most efficient way, more efficient would be to sort the array before looking for duplicates but that would modify the contents of the array at the same time.
I hope I've understand your requirements well enough.
for(int i=0;i<size;i++){
for(int j=i+1;j<size;j++){
if(streamNUM[i]==streamNUM[j]){
...........
}
}
}
I assume that u need whether there is duplication or not this may be helpful
If not comment
It's a little unclear what exactly you're looking to do here but I'm assuming as it's sudoku you're only interested in storing numbers 1-9?
If so to test for a duplicate you could iterate through the source array and use a second array (with 9 elements - I've called it flag) to hold a flag showing whether each number has been used or not.
So.. something like:
for (loop=0;loop<size;loop++) {
if (flag[streamNum[loop]]==true) {
//duplicate - do something & break this loop
break;
}
else {
flag[streamNum[loop]=true;
}
}
Here's how I'd test against Sudoku rules - it checks horizontal, vertical and 3x3 block using the idea above but here 3 different flag arrays for the 3 rules. This assumes your standard grid is held in an 81-element array. You can easily adapt this to cater for partially-completed grids..
for (loop=0;loop<9;loop++) {
flagH=[];
flagV=[];
flagS=[];
for (loop2=0;loop2<9;loop2++) {
//horizontal
if(flagH[streamNum[(loop*9)+loop2]]==true) {
duplicate
else {
flagH[streamNum[(loop*9)+loop2]]=true);
}
//column test
if(flagV[streamNum[loop+(loop2*9)]]==true) {
..same idea as above
//3x3 sub section test
basecell = (loop%3)*3+Math.floor(loop/3)*27; //topleft corner of 3x3 square
cell = basecell+(loop2%3+(Math.floor(loop2/3)*9));
if(flagS[streamNum[cell]]==true) {
..same idea as before..
}
}

fire simulation program dont know how to initialize it

The program is supposed to output a matrix of 12x24 which is bordered by 0s, has 1s in the middle, and a 2 at the location of (1,1) i do not know in which part to initialize M[row][col]=2; because anywhere i put it, it does not output the 2 to the first spot, any suggestions?
int main()
{
int M[N/2][N];
int ROWS, COLS, row, col;
int r, c;
ROWS = sizeof(M) / sizeof(M[0]);
COLS = sizeof(M[0]) / sizeof(M[0][0]);
fill(M, ROWS, COLS, 1, 1);
row=1;
col=1;
for(r=0; r< ROWS; r++)
{
for(c=0; c < COLS; c++)
{
if (r==0||r ==ROWS-1)
{
M[ROWS][COLS]=0;
}
else if(c==0||c==COLS-1)
{
M[ROWS][COLS]=0;
}
else {
M[ROWS][COLS]=1;
}
cout<< M[ROWS][COLS];
}
cout << endl;
}
print(M, ROWS, COLS);
return 0;
}
I notice you're using ROWS and COLS as array indices inside the for loops...you
probably meant to use the loop variables r and c.
Also, it's considered bad form to use upper case names for regular variables...the
convention in C is to use upper case identifiers only for macros.
I bet if you write M[1][1]=2; just before the line cout<<M[ROWS][COLS] then you will see the output you want. It is silly to do it that way, because then you will assign that single location (M[1][1]) to the same value repeatedly--to be exact, 288 times--but you cannot print the wrong value for M[1][1] if you set it to the correct value each time you print anything. There are better ways to do it, of course.
You would be much better off to cleanly separate the actions the program performs. There are really two things it must do:
Initialize the array.
Print the contents of the array.
Each of these actions should be performed by a different function. That is, call one function one time to initialize the entire array, and then call another function one time to print the entire array. This way every cell in the array is set to the correct value before any cell is printed.
If you do this, you should very easily be able to find a good place in your code to set M[1][1]=2 so that you see the correct printout.
I am assuming this is an exercise that will later be extended to do something more with the array, so that it makes sense to use an array in the first place. If so, there is a very good chance you'll have to print the array again at some point, and then you'll be very glad that you wrote a function that prints the array and does nothing else.