Recursive function throws unhandled exception at 0x79B20AD2 (ucrtbased.dll) - c++

I write minesweeper and the current task is to write a function that would uncover the areas that have no mines neighbouring to them. In the original minesweeper if you click within the area with no mines, it would open up an area until there are mines alongside its borders. For that I wrote the function unravel(). Here is the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#define Str1D vector<string>
#define Str2D vector<Str1D>
#define Int1D vector<int>
#define Int2D vector<Int1D>
void unravel(Str2D &fogofwar, Int2D &display, int x, int y) {
for (int minusrows = -1; minusrows < 2; minusrows++){ // going through the
// neighbouring cells (+ the cell itself)
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (x + minusrows > 0 && y + minuscolumns > 0 && x + minusrows < fogofwar.size() && y + minuscolumns < fogofwar[0].size()){ // checking
// if within borders
if (x > 0 && y > 0 && x < fogofwar.size() && y < fogofwar[0].size()) { // checking if the oririginal
// values are within borders
fogofwar[x + minusrows][y + minuscolumns] = to_string(display[x + minusrows][y + minuscolumns]); // revealing the
// neighbouring cells
if (display[x + minusrows][y + minuscolumns] == 0) { // if the cell is 0 on the display,
// open it and the 8 neighbouring to it cells
if (not (minusrows == 0 && minuscolumns == 0)) { // if it's not the same cell, of course,
// otherwise it's an endless cycle
unravel(fogofwar, display, x + minusrows, y + minuscolumns);
}
}
}
}
}
}
}
int main() {
int row, column, prob;
bool running = true;
cout << "Input width and height: ";
cin >> row >> column;
cout << endl << "Input mines probability (%): ";
cin >> prob;
cout << endl;
srand (time(NULL));
Int2D field(row + 1, Int1D(column + 1));
Int2D display(row + 1, Int1D(column + 1));
Str2D fogofwar(row + 1, Str1D(column + 1, "*"));
field[0][0] = 0; // field of mines
display[0][0] = 0; // display of neighbouring mines
fogofwar[0][0] = to_string(0); // what the player will see
for (int i = 1; i < row + 1; i++) { //assigning coordinates
field[i][0] = i;
display[i][0] = i;
fogofwar[i][0] = to_string(i);
}
for (int j = 1; j < column + 1; j++) { //assigning coordinates
field[0][j] = j;
display[0][j] = j;
fogofwar[0][j] = to_string(j);
}
for (int i = 1; i < row + 1; i++){ // filling the field with mines
for (int j = 1; j < column + 1; j++){
int x = rand() % 100;
if (x < prob) {
field[i][j] = 1;
}
else{
field[i][j] = 0;
}
}
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // printing field
for (int j = 0; j < column + 1; j++){
cout << " " << field[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // assigning the display of amount of neighbouring mines
for (int j = 0; j < column + 1; j++){
int count = 0;
if (i > 0 && j > 0){
for (int minusrows = -1; minusrows < 2; minusrows++){
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (i + minusrows > 0 && i + minusrows < row + 1 && j + minuscolumns > 0 && j + minuscolumns < column + 1){
if (field[i + minusrows][j + minuscolumns] == 1){
count++;
}
}
}
}
display[i][j] = count;
}
cout << " " << display[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
while (running) {
for (int i = 0; i < row + 1; i++){
for (int j = 0; j < column + 1; j++){
cout << " " << fogofwar[i][j] << " ";
}
cout << endl;
}
cout << endl;
int x, y;
cout << endl << "Input the target cell (x, y): ";
cin >> x >> y;
cout << endl;
unravel(fogofwar, display, x, y);
}
return 0;
}
If I delete the recursivity by changing unravel(fogofwar, display, x + minusrows, y + minuscolumns); to continue; within the function unravel(), it works as intended. But I need to open up the entire area where there are 0's on the display. Any way to skirt the error or fix it for good?

First of all, I am unable to reproduce the error with the information in question. Please try to specify the complete usecase along with what values you are getting into error with.
However, there is an obvious problem in the implementation of unravel.
You go over the same cell multiple times, until the memory exceeds total memory of course (I believe this is the point your program crashes)
You should maintain the slots already visited. You can do this in multiple ways. I am providing one of the ways to handle this.
Try the following code:-
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#define Str1D vector<string>
#define Str2D vector<Str1D>
#define Int1D vector<int>
#define Int2D vector<Int1D>
void unravel(Str2D &fogofwar, Int2D &display, int x, int y, vector<vector<bool> > &visited) {
for (int minusrows = -1; minusrows < 2; minusrows++){ // going through the
// neighbouring cells (+ the cell itself)
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (x + minusrows > 0 && y + minuscolumns > 0 && x + minusrows < fogofwar.size() && y + minuscolumns < fogofwar[0].size()){ // checking
// if within borders
if (x > 0 && y > 0 && x < fogofwar.size() && y < fogofwar[0].size()) { // checking if the oririginal
// values are within borders
if (x > 0 && y > 0 && x < visited.size() && y < visited[0].size()) {
cout.flush();
}
visited[x][y] = true;
fogofwar[x + minusrows][y + minuscolumns] = to_string(display[x + minusrows][y + minuscolumns]); // revealing the
// neighbouring cells
if (display[x + minusrows][y + minuscolumns] == 0) { // if the cell is 0 on the display,
// open it and the 8 neighbouring to it cells
if (not visited[x + minusrows][y + minuscolumns]) { // if it's not the same cell, of course,
// otherwise it's an endless cycle
unravel(fogofwar, display, x + minusrows, y + minuscolumns, visited);
}
}
}
}
}
}
}
int main() {
int row, column, prob;
bool running = true;
cout << "Input width and height: ";
cin >> row >> column;
cout << endl << "Input mines probability (%): ";
cin >> prob;
cout << endl;
srand (time(NULL));
Int2D field(row + 1, Int1D(column + 1));
Int2D display(row + 1, Int1D(column + 1));
Str2D fogofwar(row + 1, Str1D(column + 1, "*"));
field[0][0] = 0; // field of mines
display[0][0] = 0; // display of neighbouring mines
fogofwar[0][0] = to_string(0); // what the player will see
for (int i = 1; i < row + 1; i++) { //assigning coordinates
field[i][0] = i;
display[i][0] = i;
fogofwar[i][0] = to_string(i);
}
for (int j = 1; j < column + 1; j++) { //assigning coordinates
field[0][j] = j;
display[0][j] = j;
fogofwar[0][j] = to_string(j);
}
for (int i = 1; i < row + 1; i++){ // filling the field with mines
for (int j = 1; j < column + 1; j++){
int x = rand() % 100;
if (x < prob) {
field[i][j] = 1;
}
else{
field[i][j] = 0;
}
}
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // printing field
for (int j = 0; j < column + 1; j++){
cout << " " << field[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // assigning the display of amount of neighbouring mines
for (int j = 0; j < column + 1; j++){
int count = 0;
if (i > 0 && j > 0){
for (int minusrows = -1; minusrows < 2; minusrows++){
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (i + minusrows > 0 && i + minusrows < row + 1 && j + minuscolumns > 0 && j + minuscolumns < column + 1){
if (field[i + minusrows][j + minuscolumns] == 1){
count++;
}
}
}
}
display[i][j] = count;
}
cout << " " << display[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
while (running) {
for (int i = 0; i < row + 1; i++){
for (int j = 0; j < column + 1; j++){
cout << " " << fogofwar[i][j] << " ";
}
cout << endl;
}
cout << endl;
int x, y;
cout << endl << "Input the target cell (x, y): ";
cin >> x >> y;
cout << endl;
vector<vector<bool> > visited(row+1, vector<bool>(column+1, false));
unravel(fogofwar, display, x, y, visited);
}
return 0;
}
The change is that I am maintaining a visited array, and I never go back to the spot I have already gone to before in unravel.

Related

Smith Waterman for C++ (Visual Studio 14.0)

I would like to kill two birds with one stone, as the questions are very similiar:
1:
I followed this code on github Smith Waterman Alignment to create the smith-waterman in C++. After some research I understood that implementing
double H[N_a+1][N_b+1]; is not possible (anymore) for the "newer" C++ versions. So to create a constant variable I changed this line to:
double **H = new double*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
H[i] = new double[nSynth + 1];
and also the same scheme for int I_i[N_a+1][N_b+1], I_j[N_a+1][N_b+1]; and so one (well, everywhere, where a two dimensional array exists). Now I'm getting the exception:
Unhandled exception at 0x00007FFF7B413C58 in Smith-Waterman.exe: Microsoft C
++ exception: std :: bad_alloc at location 0x0000008FF4F9FA50.
What is wrong here? Already debugged, and the program throws the exceptions above the for (int i = 0; i < nReal + 1; i++).
2: This code uses std::strings as parameters. Would it be also possible to create a smith waterman algortihm for cv::Mat?
For maybe more clarification, my full code looks like this:
#include "BinaryAlignment.h"
#include "WallMapping.h"
//using declarations
using namespace cv;
using namespace std;
//global variables
std::string bin;
cv::Mat temp;
std::stringstream sstrMat;
const int maxMismatch = 2;
const float mu = 0.33f;
const float delta = 1.33;
int ind;
BinaryAlignment::BinaryAlignment() { }
BinaryAlignment::~BinaryAlignment() { }
/**
*** Convert matrix to binary sequence
**/
std::string BinaryAlignment::matToBin(cv::Mat src, std::experimental::filesystem::path path) {
cv::Mat linesMat = WallMapping::wallMapping(src, path);
for (int i = 0; i < linesMat.size().height; i++) {
for (int j = 0; j < linesMat.size().width; j++) {
if (linesMat.at<Vec3b>(i, j)[0] == 0
&& linesMat.at<Vec3b>(i, j)[1] == 0
&& linesMat.at<Vec3b>(i, j)[2] == 255) {
src.at<int>(i, j) = 1;
}
else {
src.at<int>(i, j) = 0;
}
sstrMat << src.at<int>(i, j);
}
}
bin = sstrMat.str();
return bin;
}
double BinaryAlignment::similarityScore(char a, char b) {
double result;
if (a == b)
result = 1;
else
result = -mu;
return result;
}
double BinaryAlignment::findArrayMax(double array[], int length) {
double max = array[0];
ind = 0;
for (int i = 1; i < length; i++) {
if (array[i] > max) {
max = array[i];
ind = i;
}
}
return max;
}
/**
*** Smith-Waterman alignment for given sequences
**/
int BinaryAlignment::watermanAlign(std::string seqSynth, std::string seqReal, bool viableAlignment) {
const int nSynth = seqSynth.length(); //length of sequences
const int nReal = seqReal.length();
//H[nSynth + 1][nReal + 1]
double **H = new double*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
H[i] = new double[nSynth + 1];
cout << "passt";
for (int m = 0; m <= nSynth; m++)
for (int n = 0; n <= nReal; n++)
H[m][n] = 0;
double temp[4];
int **Ii = new int*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
Ii[i] = new int[nSynth + 1];
int **Ij = new int*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
Ij[i] = new int[nSynth + 1];
for (int i = 1; i <= nSynth; i++) {
for (int j = 1; j <= nReal; j++) {
temp[0] = H[i - 1][j - 1] + similarityScore(seqSynth[i - 1], seqReal[j - 1]);
temp[1] = H[i - 1][j] - delta;
temp[2] = H[i][j - 1] - delta;
temp[3] = 0;
H[i][j] = findArrayMax(temp, 4);
switch (ind) {
case 0: // score in (i,j) stems from a match/mismatch
Ii[i][j] = i - 1;
Ij[i][j] = j - 1;
break;
case 1: // score in (i,j) stems from a deletion in sequence A
Ii[i][j] = i - 1;
Ij[i][j] = j;
break;
case 2: // score in (i,j) stems from a deletion in sequence B
Ii[i][j] = i;
Ij[i][j] = j - 1;
break;
case 3: // (i,j) is the beginning of a subsequence
Ii[i][j] = i;
Ij[i][j] = j;
break;
}
}
}
//Print matrix H to console
std::cout << "**********************************************" << std::endl;
std::cout << "The scoring matrix is given by " << std::endl << std::endl;
for (int i = 1; i <= nSynth; i++) {
for (int j = 1; j <= nReal; j++) {
std::cout << H[i][j] << " ";
}
std::cout << std::endl;
}
//search H for the moaximal score
double Hmax = 0;
int imax = 0, jmax = 0;
for (int i = 1; i <= nSynth; i++) {
for (int j = 1; j <= nReal; j++) {
if (H[i][j] > Hmax) {
Hmax = H[i][j];
imax = i;
jmax = j;
}
}
}
std::cout << Hmax << endl;
std::cout << nSynth << ", " << nReal << ", " << imax << ", " << jmax << std::endl;
std::cout << "max score: " << Hmax << std::endl;
std::cout << "alignment index: " << (imax - jmax) << std::endl;
//Backtracing from Hmax
int icurrent = imax, jcurrent = jmax;
int inext = Ii[icurrent][jcurrent];
int jnext = Ij[icurrent][jcurrent];
int tick = 0;
char *consensusSynth = new char[nSynth + nReal + 2];
char *consensusReal = new char[nSynth + nReal + 2];
while (((icurrent != inext) || (jcurrent != jnext)) && (jnext >= 0) && (inext >= 0)) {
if (inext == icurrent)
consensusSynth[tick] = '-'; //deletion in A
else
consensusSynth[tick] = seqSynth[icurrent - 1]; //match / mismatch in A
if (jnext == jcurrent)
consensusReal[tick] = '-'; //deletion in B
else
consensusReal[tick] = seqReal[jcurrent - 1]; //match/mismatch in B
//fix for adding first character of the alignment.
if (inext == 0)
inext = -1;
else if (jnext == 0)
jnext = -1;
else
icurrent = inext;
jcurrent = jnext;
inext = Ii[icurrent][jcurrent];
jnext = Ij[icurrent][jcurrent];
tick++;
}
// Output of the consensus motif to the console
std::cout << std::endl << "***********************************************" << std::endl;
std::cout << "The alignment of the sequences" << std::endl << std::endl;
for (int i = 0; i < nSynth; i++) {
std::cout << seqSynth[i];
};
std::cout << " and" << std::endl;
for (int i = 0; i < nReal; i++) {
std::cout << seqReal[i];
};
std::cout << std::endl << std::endl;
std::cout << "is for the parameters mu = " << mu << " and delta = " << delta << " given by" << std::endl << std::endl;
for (int i = tick - 1; i >= 0; i--)
std::cout << consensusSynth[i];
std::cout << std::endl;
for (int j = tick - 1; j >= 0; j--)
std::cout << consensusReal[j];
std::cout << std::endl;
int numMismatches = 0;
for (int i = tick - 1; i >= 0; i--) {
if (consensusSynth[i] != consensusReal[i]) {
numMismatches++;
}
}
viableAlignment = numMismatches <= maxMismatch;
return imax - jmax;
}
Thanks!

Finding all saddle points in a matrix c++

I'm working on a code that finds all saddle points in a matrix. Both smallest in their row and biggest in their column, and biggest in their row and smallest in their column fall under the definition (of my university) of a saddle point. Being a beginner I managed to get half of it done (finding saddle points which are smallest in their row and biggest in their column) by copying parts of what we've done in class and typing it myself. I have been stuck on it for quite some time and can't figure how to add the saddle points which are biggest in their row and smallest in their column to the program.
This is what I have so far:
#include <iostream>
#include <cstdlib>
using namespace std;
int a[10][10];
int x, y;
int pos_max(int j) //saddle points check
{
int max = 0;
for (int i = 1; i <= x - 1; i++) {
if (a[i][j] > a[max][j]) {
max = i;
}
}
return max;
}
int main() {
cout << "Enter the number of rows: ";
cin >> x;
cout << "Enter the number of columns: ";
cin >> y;
cout << "----------------------------" << endl;
for (int i = 0; i <= x - 1; i++) //input of the matrix
for (int j = 0; j <= y - 1; j++) {
cout << "a[" << i + 1 << ", " << j + 1 << "] = ";
cin >> a[i][j];
}
cout << "----------------------------\n";
for (int i = 0; i <= x - 1; i++) //visualization of the matrix
{
for (int j = 0; j <= y - 1; j++)
cout << a[i][j] << " ";
cout << endl;
}
cout << "----------------------------\n";
int r;
int flag = 0;
int i = y;
for (int j = 0; j <= y - 1; j++) {
r = pos_max(j);
for (i = 0; i <= y - 1; i++) {
if (a[r][i] < a[r][j]) {
break;
}
}
if (i == y) {
cout << "Saddle points are: ";
cout << "a[" << r + 1 << ", " << j + 1 << "] = " << a[r][j] << "\n";
flag = 1;
}
}
if (flag == 0) {
cout << "No saddle points\n";
}
cout << "----------------------------\n";
return 0;
}
First, there is a logical error with your code. In the pos_max function, it will return the index of the element which is maximum in the column. There can be a case when there are multiple maximum with the same value in the column, however, it returns the one which is not the minimum in the row, hence your program won't be able to print that saddle point.
To solve this, you can either return an array of all indices which are maximum in a column and then check for each of those points if it's minimum in their respective column, but I think it's not a very elegant solution. In any case, you will again have to write the entire code for the other condition for saddle points, minimum in column and maximum in row.
Hence, I would suggest a change in strategy. You create 4 arrays, max_row, max_col, min_row, min_col, where each array stores the minimum / maximum in that row / column respectively. Then you can traverse the array and check if that point satisfies saddle point condition.
Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
int a[10][10];
int max_row[10], max_col[10], min_row[10], min_col[10];
int x, y;
bool is_saddle(int i, int j) {
int x = a[i][j];
return (max_row[i] == x && min_col[j] == x) || (min_row[i] == x && max_col[j] == x);
}
int main() {
/* code to input x, y and the matrix
...
*/
/* code to visualize the matrix
...
*/
/* populating max and min arrays */
for (int i = 0; i <= x-1; ++i) {
max_row[i] = a[i][0], min_row[i] = a[i][0];
for (int j = 0; j <= y-1; ++j) {
max_row[i] = max(max_row[i], a[i][j]);
min_row[i] = min(min_row[i], a[i][j]);
}
}
for (int j = 0; j <= y-1; ++j) {
max_col[j] = a[0][j], min_col[j] = a[0][j];
for (int i = 0; i <= x-1; ++i) {
max_col[j] = max(max_col[j], a[i][j]);
min_col[j] = min(min_col[j], a[i][j]);
}
}
/* Check for saddle point */
for (int i = 0; i <= x-1; ++i) {
for (int j = 0; j <= y-1; ++j) {
if (is_saddle(i, j)) {
cout << "Saddle points are: ";
cout << "a[" << i + 1 << ", " << j + 1 << "] = " << a[i][j] << "\n";
flag = 1;
}
}
}
if (flag == 0) {
cout << "No saddle points\n";
}
cout << "----------------------------\n";
return 0;
}
#include <iostream>
using namespace std;
int getMaxInRow(int[][5], int, int, int);
int getMinInColumn(int[][5], int, int, int);
void getSaddlePointCordinates(int [][5],int ,int );
void getInputOf2dArray(int a[][5], int, int);
int main()
{
int a[5][5] ;
int rows, columns;
cin >> rows >> columns;
getInputOf2dArray(a, 5, 5);
getSaddlePointCordinates(a,rows,columns);
}
void getInputOf2dArray(int a[][5], int rows, int columns)
{
for (int i = 0; i < rows; i = i + 1)
{
for (int j = 0; j < columns; j = j + 1)
{
cin >> a[i][j];
}
}
}
void getSaddlePointCordinates(int a[][5],int rows,int columns)
{
int flag = 0;
for (int rowNo = 0; rowNo < 5; rowNo++)
{
for (int columnNo = 0; columnNo < 5; columnNo++)
{
if (getMaxInRow(a, rows, columns, rowNo) == getMinInColumn(a, rows, columns, columnNo))
{
flag = 1;
cout << rowNo << columnNo;
}
}
}
if (flag == 0)
cout << "no saddle point";
cout << "\n";
}
int getMaxInRow(int a[][5], int row, int column, int rowNo)
{
int max = a[rowNo][0];
for (int i = 1; i < column; i = i + 1)
{
if (a[rowNo][i] > max)
max = a[rowNo][i];
}
return max;
}
int getMinInColumn(int a[][5], int row, int column, int columnNo)
{
int min = a[0][columnNo];
for (int i = 1; i < row; i = i + 1)
{
if (a[i][columnNo] < min)
min = a[i][columnNo];
}
return min;
}
just take the reference arr(ref[size]) // memorization method to check the minimum and maximum value in it.
Here is the Code Implementation with time complexity O(n *n) & space complexity O(n):
#include <bits/stdc++.h>
using namespace std;
#define size 5
void util(int arr[size][size], int *count)
{
int ref[size]; // array to hold all the max values of row's.
for(int r = 0; r < size; r++)
{
int max_row_val = arr[r][0];
for(int c = 1; c < size; c++)
{
if(max_row_val < arr[r][c])
max_row_val = arr[r][c];
}
ref[r] = max_row_val;
}
for(int c = 0; c < size; c++)
{
int min_col_val = arr[0][c];
for(int r = 1; r < size; r++) // min_val of the column
{
if(min_col_val > arr[r][c])
min_col_val = arr[r][c];
}
for(int r = 0; r < size; r++) // now search if the min_val of col and the ref[r] is same and the position is same, if both matches then print.
{
if(min_col_val == ref[r] && min_col_val == arr[r][c])
{
*count += 1;
if((*count) == 1)
cout << "The cordinate's are: \n";
cout << "(" << r << "," << c << ")" << endl;
}
}
}
}
// Driver function
int main()
{
int arr[size][size];
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
cin >> arr[i][j];
}
int count = 0;
util(arr, &count);
if(!count)
cout << "No saddle points" << endl;
}
// Test case -> Saddle Point
/*
Input1:
1 2 3 4 5
6 7 8 9 10
1 2 3 4 5
6 7 8 9 10
0 2 3 4 5
Output1:
The cordinate's are:
(0,4)
(2,4)
(4,4)
Input2:
1 2 3 4 5
6 7 8 9 1
10 11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Output2:
No saddle points
*/

Two-Dimensional Array Searching Algorithm Optimisation

I have been given a "Sand box" of variable length and width. I've been given instructions to find a "shovel" of static size, which may be oriented either horizontally or vertically. I implement the following algorithm in order to search the least amount of times to find one valid location (one which corresponds to a "part of the object") in the grid:
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; j < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
In this case, the "Sand box" will be tested by the function as described below.
I completely recreate this scenario with a "Sand box" whose size is fixed (though easily manipulated) whose shovel is still randomly placed and oriented within the following code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
const int ROW = 12;
const int COL = 16;
char sandbox[ROW][COL];
bool probeSandBoxTwo(char c, int i);
void displayResults(int sCount, bool found, int x, int y);
void displaySandbox();
void displaySearchPattern();
void fillSandbox();
void placeShovel();
int main() {
fillSandbox();
placeShovel();
displaySandbox();
//define your variables here
bool found;
int nShift,
sCount,
shovelSize,
x,
y;
found = false;
nShift = 0;
shovelSize = 4;
sCount = 0;
for(int i = 0; i < ROW && !found; i++) {
for(int j = 0; j < COL && !found; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
x = i;
y = j + nShift;
sCount++;
cout << "Search conducted at (" << i << ", " << (j + nShift) << ")" << endl;
}
if(nShift >= shovelSize - 1 || nShift > ROW) {
nShift = 0;
} else {
nShift++;
}
}
displayResults(sCount, found, x, y);
displaySearchPattern();
}
bool probeSandBoxTwo(char c, int i) {
if(sandbox[c-'A'][i-1] == 'X') {
return true;
} else {
return false;
}
}
void displayResults(int sCount, bool found, int x, int y) {
cout << endl;
cout << "Total searches: " << sCount << endl;
cout << endl;
if(found) {
cout << "Shovel found at coordinates: (" << x << ", " << y << ")" << endl;
}
}
void displaySandbox() {
cout << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
cout << sandbox[i][j];
}
cout << endl;
}
cout << endl;
}
void displaySearchPattern() {
int nShift = 0;
int shovelSize = 4;
cout << endl << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
if(!((j + nShift) % shovelSize)) {
cout << 'o';
} else {
cout << '.';
}
}
if(nShift >= shovelSize - 1 || nShift > COL) {
nShift = 0;
} else {
nShift++;
}
cout << endl;
}
}
void fillSandbox() {
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COL; j++) {
sandbox[i][j] = '.';
}
}
}
void placeShovel() {
srand(time(NULL));
int shovelRow,
shovelCol,
shovelSize = 4;
if(rand() % 2) {
//horizontal
shovelRow = rand() % ROW + 1;
shovelCol = rand() % (COL - (shovelSize - 1)) + 1;
for(int i = shovelCol - 1; i < shovelSize + (shovelCol - 1); i++) {
sandbox[shovelRow - 1][i] = 'X';
}
} else {
//vertical
shovelRow = rand() % (ROW - (shovelSize - 1)) + 1;
shovelCol = rand() % COL + 1;
for(int i = shovelRow - 1; i < shovelSize + (shovelRow - 1); i++) {
sandbox[i][shovelCol - 1] = 'X';
}
}
}
In this code, I also graphically display the pattern (when run) with which my algorithm searches.
Is this truly the optimal search pattern for such a scenario, is my implementation correct, and if so, why might I be having incorrect results returned?
A given test driver reports the following results:
The source code for this result (and its test driver).
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; (j + nShift) < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
This corrects an error in the conditional portion of the for loop header which did not account for the index-shifting variable nShift.

Reading matrix from txt file to do Gaussian Elimination (C++)

So I'm trying to read a matrix A from a text file, which it does correctly. A vector B is entered by the user. Then I want to perform Gaussian Elimination (Ax = b) to get the solution vector x. The values I get for x are -1.#IND and I have no idea why...I'm guessing something is going wrong in SystemSolution?
#include <iostream>
#include <vector>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
//this program does gaussian elimination for a matrix Ax=b
vector<double> SystemSolution(vector<vector<double>> A, vector<double> b)
{
//Determine and test size of a matrix
int n = A.size();
for (int i = 0; i < n; i++)
if (n != A[i].size())
throw "Error! Number of rows and columns of matrix must be equal!";
vector<double> x(b.size());
//x is the vector of solutions
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
//Finding pivot
double pivot = A[i][i];
int index = i;
for (int k = i + 1; k < n; k++)
{
if (pivot > abs(A[k][i]))
{
index = k;
pivot = A[k][i];
}
}
//Row exchange
for (int k = 0; k < n; k++)
{
double tmp = A[i][k];
A[i][k] = A[index][k];
A[index][k] = tmp;
}
//Elimination
double coefficient = -(A[j][i] / A[i][i]);
for (int k = i; k < n; k++)
{
A[j][k] += coefficient*A[i][k];
}
b[j] += coefficient*b[i];
}
}
//Back-substitution
x[n - 1] = b[n - 1] / A[n - 1][n - 1];
for (int i = n - 2; i >= 0; i--)
{
double sum = 0;
for (int j = i; j < n; j++)
{
sum += x[j] * A[i][j];
}
x[i] = (b[i] - sum) / A[i][i];
}
return x;
}
void PrintVector(const vector<double> &b)
{
for (int i = 0; i < b.size(); i++)
cout << setiosflags(ios::showpoint | ios::fixed | ios::right)
<< setprecision(4)
<< setw(8) << b[i] << endl;
}
void PrintMatrix(const vector<vector<double> > &A)
{
for (int i = 0; i < A.size(); i++)
{
for (int j = 0; j < A[i].size(); j++)
cout << setiosflags(ios::showpoint | ios::fixed | ios::right)
<< setprecision(4)
<< setw(8) << A[i][j];
cout << endl;
}
}
int main()
{
int n;
cout << "Please enter the number of rows/columns:";
cin >> n;
ifstream matrixFile;
matrixFile.open("matrix.txt");
if (matrixFile.is_open()){
//matrix A values
vector<vector<double>> A(n, vector<double>(n));
vector<double> b(n);
string line;
int col = 0;
int row = 0;
while (getline(matrixFile, line)){
istringstream stream(line);
int x;
col = 0; //reset
while (stream >> x){
A[row][col] = x;
col++;
}
row++;
}
cout << "Please enter vector b:"<<endl;
//vector b values
for (int i = 0; i < row; i++)
{
cout << "b[" << i + 1 << "]= ";
cin >> b[i];
}
vector<double> x = SystemSolution(A, b);
cout << "- SOLUTIONS -" << endl;
cout << "Matrix:" << endl;
PrintMatrix(A);
cout << "\nVector x:" << endl;
PrintVector(x);
}
else{
cout << "File failed to open!";
}
matrixFile.close();
return 0;
}
There could be some divisions by zero in your code:
double coefficient = -(A[j][i] / A[i][i]);
/* .. */
x[n - 1] = b[n - 1] / A[n - 1][n - 1];
/* .. */
x[i] = (b[i] - sum) / A[i][i];
Check out Gauss-elimination here:
Square Matrix Inversion in C
Review and debug yours.

how to check if all values in an array are equal to eachother. C++

I guess the problem is... Its not saying all of the sums are equal, even though they are.
And I know, this is some shitty programming. xD I'll put some stars next to my problem.
Thank you for your help.
#include <iostream>
using namespace std;
//function that passes a variable through and checks and sees if that variable has been used before.
bool checkArray(int pass[5][5], int toCheck)
{
bool check = false;
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
if(pass[i][j] == toCheck)
{
check = true;
}
}
}
return check;
}
int main(){
bool allTrue;
int array[5][5] = {0};
int num;
int count=0;
int arraySums[12];
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
do // do while executes when number is 1-25, and a number has not been found when run through the function to check if it is found in the array.
{
cout << "Please enter a number that will go in slot (" << i + 1 << ")(" << j + 1 << "): ";
cin >> num;
}
while(((num < 1) || (num > 25)) || (checkArray(array, num) == true));
array[i][j] = num;
}
}
//populate the arraySums Array.
//for(int i=0; i<2)
for(int i = 0; i < 5; i++) // prints out array
{
for(int j = 0; j < 5; j++)
{
cout << " | " << array[i][j] << " ";
}
cout << endl;
count++;
}
//for horizontal sums
arraySums[0]=array[0][0] + array[0][1] + array[0][2] + array[0][3] + array[0][4];
arraySums[1]=array[1][0] + array[1][1] + array[1][2] + array[1][3] + array[1][4];
arraySums[2]=array[2][0] + array[2][1] + array[2][2] + array[2][3] + array[2][4];
arraySums[3]=array[3][0] + array[3][1] + array[3][2] + array[3][3] + array[3][4];
arraySums[4]=array[4][0] + array[4][1] + array[4][2] + array[4][3] + array[4][4];
//for vertical sums
arraySums[5]=array[0][0] + array[1][0] + array[2][0] + array[3][0] + array[4][0];
arraySums[6]=array[0][1] + array[1][1] + array[2][1] + array[3][1] + array[4][1];
arraySums[7]=array[0][2] + array[1][2] + array[2][2] + array[3][2] + array[4][2];
arraySums[8]=array[0][3] + array[1][3] + array[2][3] + array[3][3] + array[4][3];
arraySums[9]=array[0][4] + array[1][4] + array[2][4] + array[3][4] + array[4][4];
//for diagonal sums
arraySums[10]=array[0][0] + array[1][1] + array[2][2] + array[3][3] + array[4][4];
arraySums[11]=array[0][4] + array[1][3] + array[2][2] + array[3][1] + array[4][0];
//to display horizontal sums
int count2=0;
for(int i = 0; i<5; i++)
{
cout << "Horizontal sum for row: " << count2+1 << " is " << arraySums[i] << endl;
count2++;
}
//to display the vertical sums.
count2=0;
for(int i = 5; i<10; i++)
{
cout << "Vertical sum for row: " << count2+1 << " is " << arraySums[i] << endl;
count2++;
}
//to display both diagonal sums
cout << "The diagonal sum from left to right is: " << arraySums[10] << endl;
cout << "The diagonal sum from right to left is: " << arraySums[11] << endl;
//*************************************************************************************************************
for(int i=0; i<13; i++)
{
if(!(arraySums[i]==arraySums[i+1]))
{
allTrue=false;
break;
}
}
if(allTrue==true)
{
cout<< "All the values are equal to each other." << endl;
}
}
In the last iteration of the loop you are comparing arraySums[12]==arraySums[13].This array only ha 12 values, numbered from 0-11.
Your for loop should read
for(int i=0; i<11; i++)
Yes that is 11. You can only make 11 comparisons between 12 data sets, otherwise what are you comparing the last one to?
EDIT: The answer saying that allTrue is uninitialised has gone missing, so I will say it here. You must initialise allTrue
bool allTrue = true;
Is standard algorithm ok?
If so, you can try count, or search_n.
count version:
bool bAllTrue = (count(array[0][0], array[5][0], array[0][0]),25);
search_n version:
bAllTrue = search_n(&array[0][0], &array[5][0], array[0][0], 25);