Random unique number arrays comparison C++ - c++

I have two 2D arrays of type integer. I assign random values into both theses arrays. The values in the first column represent the x value for a and b, and the values in the second column represent the y value for a and b.
Declaring the arrays
int ROW(12), COLUMN(2);
int a[ROW][COLUMN];
int b[ROW][COLUMN];
Assigning random values to the arrays
for (int i(0); i < ROW; i++)
{
a[i][0] = Random(SIZEX - 2); //horizontal coordinate in range [1..(SIZEX - 2)]
a[i][1] = Random(SIZEY - 2); //vertical coordinate in range [1..(SIZEY - 2)]
}
for (int i(0); i < (ROW - 4); i++)
{
b[i][0] = Random(SIZEX - 2); //horizontal coordinate in range [1..(SIZEX - 2)]
b[i][1] = Random(SIZEY - 2); //vertical coordinate in range [1..(SIZEY - 2)]
}
I need to find a way in which I can compare the x and y value of an row, with the x and y value of each other row in each array aswell as with the other array and make sure each combination of x and y is unique for both of the arrays.
As the coordinates will relate to the position in another array.
I have a very messy solution which will work for one of the arrays.
for (int i(0); i < COLUMN; ++i)
{
if (i == 0)
{
while (b[i][0] == spot.x)
b[i][0] = Random(SIZEX - 2);
}
if (i == 1)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
if (i == 2)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 2][0]) || (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
if (i == 3)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 3][0]) || (b[i][0] == b[i - 2][0]) || (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
if (i == 4)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 4][0]) || (b[i][0] == b[i - 3][0]) || (b[i][0] == b[i - 2][0])
|| (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
if (i == 5)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 5][0]) || (b[i][0] == b[i - 4][0]) || (b[i][0] == b[i - 3][0])
|| (b[i][0] == b[i - 2][0]) || (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
if (i == 6)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 6][0]) || (b[i][0] == b[i - 5][0]) || (b[i][0] == b[i - 4][0])
|| (b[i][0] == b[i - 3][0]) || (b[i][0] == b[i - 2][0]) || (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
if (i == 7)
{
while ((b[i][0] == spot.x) || (b[i][0] == b[i - 7][0]) || (b[i][0] == b[i - 6][0]) || (b[i][0] == b[i - 5][0])
|| (b[i][0] == b[i - 4][0]) || (b[i][0] == b[i - 3][0]) || (b[i][0] == b[i - 2][0])
|| (b[i][0] == b[i - 1][0]))
b[i][0] = Random(SIZEX - 2);
}
}
But it only compares the x (first column). spot represents a struct variable.

May be you can try
for (int i=0;i<12;i++)
{for (int k=i+1;k<12;k++)
{if (a[i][0]==a[k][0])
cout<<"a["<<i<<"][0] same as a["<<k<<"][0]"<<endl;//you can assign a new number to a[k][0]
}};

Related

How can I fix the "Invalid memory reference" error in my code?

I'm working on a maze-solver robot for my arduino project. I want my robot to memorize the maze and then find the shortest path. I keep having a problem when the char array's lenght is 3.
The problem appears when the lenght is <= 3, so I tried diffrent stuff to make a particular case out of that, that's why the if (strlen(a) > 3) is there.
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
char a[] = "LLLBLLLRBLLBSRSRS";
char b[200];
while(strcmp(a, b) != 0) {
strcpy(b, a); //sa verific daca se schimba sirul, daca nu inseamna ca a ajuns la minim
for(int i = 0; i < strlen(a) - 2; i++)
{
if(a[i] == 'L' && a[i + 1] == 'B' && a[i + 2] == 'R') //if urile astea cauta combinatii de cate 3 miscari sa optimizezi drumul
{
a[i] = 'B';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'L' && a[i + 1] == 'B' && a[i + 2] == 'S')
{
a[i] = 'R';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'L' && a[i + 1] == 'B' && a[i + 2] == 'L')
{
a[i] = 'S';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'S' && a[i + 1] == 'B' && a[i + 2] == 'L')
{
a[i] = 'R';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'S' && a[i + 1] == 'B' && a[i + 2] == 'S')
{
a[i] = 'B';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'R' && a[i + 1] == 'B' && a[i + 2] == 'L')
{
a[i] = 'B';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
}
cout << a << endl;
}
return 0;
}
This is the output:
LLSLLBRRSRS
LLSLBRSRS
LLSBSRS
LLBRS
LBS
and then the error message Runtime error(Exit status:139(Invalid memory reference)).
The goal is to make the last output be R, because LBS means R.
Thanks for the attention!
The reason for invalid memory reference is in the loop consition:
for(int i = 0; i < strlen(a) - 2; i++)
you are accessing a[i + 2] inside loop so the last iteration must end at i < strlen(a) - 3:
for(int i = 0; i < strlen(a) - 3; i++)
this just fixes your memory problem. you still get LBS as the last output.

Watershed implementation in C++

I'm working in the watershed algortih in C++. I have implemented a source that i've found but i didn't get the expected results. I obtain:
[
But the result should be this:
[
I have charge the image .bmp into a matrix an then i obtain the Gradient of the image using the Sobel operator.
My wathershed algorith now is:
void Watershed() {
stack<punto> s;
punto p, neighbour;
C_Matrix prueba3 (Gradiente.FirstRow(), Gradiente.LastRow(), Gradiente.FirstCol(), Gradiente.LastCol(), -1);
int auxU, auxV, Eaux, L=1;
for (double g = Gradiente.Min(); g <= Gradiente.Max(); g++) {
for (int i = Gradiente.FirstRow(); i <= Gradiente.LastRow(); i++) {
for (int j = Gradiente.FirstCol(); j <= Gradiente.LastCol(); j++) {
if (Gradiente(i, j) == g) {
p.Guarda(i, j);
s.push(p);
}
while (s.empty() == 0) {
p = s.top();
s.pop();
auxU = p.x;
auxV = p.y;
Eaux = -1;
// 8-connectivity
for (int i = 0; i < 8; i++) {
if (i == 0)
neighbour.Guarda(auxU - 1, auxV - 1);
else if (i == 1)
neighbour.Guarda(auxU, auxV - 1);
else if (i == 2)
neighbour.Guarda(auxU + 1, auxV - 1);
else if (i == 3)
neighbour.Guarda(auxU - 1, auxV);
else if (i == 4)
neighbour.Guarda(auxU + 1, auxV);
else if (i == 5)
neighbour.Guarda(auxU - 1, auxV + 1);
else if (i == 6)
neighbour.Guarda(auxU, auxV + 1);
else
neighbour.Guarda(auxU + 1, auxV + 1);
if (neighbour.x >= Gradiente.FirstRow() && neighbour.x <= Gradiente.LastRow()
&& neighbour.y >= Gradiente.FirstCol() && neighbour.y <= Gradiente.LastCol()) {
if (prueba3(neighbour.x, neighbour.y) > 0) {
if (Eaux == -1) {
Eaux = prueba3(neighbour.x, neighbour.y);
}
else if (prueba3(neighbour.x, neighbour.y) != Eaux)
Eaux = 0;
}
}
}
if (auxU >= Gradiente.FirstRow() && auxU <= Gradiente.LastRow()
&& auxV >= Gradiente.FirstCol() && auxV <= Gradiente.LastCol()) {
if (Eaux >= 0) {
prueba3(auxU, auxV) = Eaux;
}
else {
prueba3(auxU, auxV) = L;
L++;
}
}
else {
C_Print("Se sale");
C_PrintNum("AuxU", auxU);
C_PrintNum("AuxV", auxV);
}
}
}
}
}
C_PrintNum("L = ", L);
double max = prueba3.Max();
if (max > 255.0) {
prueba3.Stretch(0, 255);
}
aux = C_Image(prueba3);
}
I don't know where is the fail, maybe my source has mistakes.

C++ Run time efficiency

I'm creating a hex board out of nodes.Everything I have in this bit of code works perfectly. My problem is the item that is starred slows down this loop from taking ~1 second to about 1 minute. It isn't the number of items in the vector because if i remove them all except the last one it still takes ~1 minute. either way there are no run time errors.
for (x = 0; x < size; ++x)
{
for (y = 0; y < size; ++y)
{
this->nodes[x][y].neighbors = std::vector<node>(6);
if ((x == 0) && (y == 0))
{
this->nodes[x][y].neighbors =
{
nodes[x + 1][y],
this->nodes[x][y + 1]
};
}
else if ((x == 0) && (y == max))
{
this->nodes[x][y].neighbors =
{
this->nodes[x + 1][y],
this->nodes[x][y - 1],
this->nodes[x + 1][y - 1]
};
}
else if ((x == max) && (y == 0))
{
this->nodes[x][y].neighbors =
{
this->nodes[x - 1][y],
this->nodes[x][y + 1],
this->nodes[x - 1][y + 1]
};
}
else if ((x == max) && (y == max))
{
this->nodes[x][y].neighbors =
{
this->nodes[x - 1][y],
this->nodes[x][y - 1]
};
}
else if (y == 0 && (x != 0 && x != max))
{
this->nodes[x][y].neighbors =
{
this->nodes[x - 1][y],
this->nodes[x + 1][y],
this->nodes[x - 1][y + 1],
this->nodes[x][y + 1]
};
}
else if (y == max && (x != 0 && x != max))
{
this->nodes[x][y].neighbors =
{
this->nodes[x - 1][y],
this->nodes[x + 1][y],
this->nodes[x - 1][y - 1],
this->nodes[x][y - 1]
};
}
else if (x == 0 && (y != 0 && y != max))
{
this->nodes[x][y].neighbors =
{
this->nodes[x][y - 1],
this->nodes[x][y + 1],
this->nodes[x + 1][y],
this->nodes[x + 1][y - 1]
};
}
else if (x == max && (y != 0 && y != max))
{
this->nodes[x][y].neighbors =
{
this->nodes[x][y - 1],
this->nodes[x][y + 1],
this->nodes[x - 1][y - 1],
this->nodes[x - 1][y]
};
}
else
{
this->nodes[x][y].neighbors =
{
this->nodes[x + 1][y],
this->nodes[x - 1][y],
this->nodes[x][y - 1],
this->nodes[x + 1][y - 1],
this->nodes[x][y + 1],
this->nodes[x - 1][y + 1]
};
}
}
}
Given the idea is to track neighbours that you know have been pre-created, you probably only want to keep a reference or pointer to them; you should not copy the nodes by value as you currently do.
You could use vector<reference_wrapper<node>> or vector<node*>, with respective initialisation like this:
nodes[x][y].neighbors = { ref(nodes[a][b]), ref(nodes[c][d])... };
nodes[x][y].neighbors = { &nodes[a][b], &nodes[c][d], ... };
With pointers, when you access neighbors[n] you'll obviously need to dereference the pointer too.
Regarding why it was so slow... the copying by value meant copying nodes into neighbours was copying all those neighbouring node's neighbours, and their neighbours, ad nauseum... getting slower and slower as the number of nodes with long neighbour hierarchies increased.
The slowness comes from 2 things:
The last else clause gets hit the most.
The last clause copies more node items than the rest
A few suggestions:
Use pointers or indexes not node objects for neighbors. Less copying.
It will be faster to have a fixed size array for neighbors. Will improve locality and memory significantly. You'll have to add a neighbor count for that array.

Entering into the wrong If statement

the program does not enter the if statement it suppose to enter.for example when the sentence1 is oguzhan and the sentence2 is bugrahan for first characters it should enter the first if statement end substitution should be 4 but it doesn't.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
int main() {
char sentence1[50];
char sentence2[50];
int m, n, k, l;
int i, j, substitution;
cout << "Enter the first word:" << endl;
cin >> sentence1;
cout << "Enter the second word:" << endl;
cin >> sentence2;
m = strlen(sentence1);
n = strlen(sentence2);
int cost[m + 1][n + 1];
cost[0][0] = 0;
for (i = 1; i < m + 1; i++) {
cost[i][0] = cost[i - 1][0] + 2;
}
for (j = 1; j < n + 1; j++) {
cost[0][j] = cost[0][j - 1] + 2;
}
for (i = 1; i < m + 1; i++) {
for (j = 1; j < n + 1; j++) {
if ((sentence1[i - 1] == 'a' || sentence1[i - 1] == 'u' ||
sentence1[i - 1] == 'e' || sentence1[i - 1] == 'i' ||
sentence1[i - 1] == 'o') &&
(sentence2[j - 1] != 'a' || sentence2[j - 1] != 'u' ||
sentence2[j - 1] != 'e' || sentence2[j - 1] != 'i' ||
sentence2[j - 1] != 'o')) {
substitution = 4;
}
if ((sentence1[i - 1] != 'a' || sentence1[i - 1] != 'u' ||
sentence1[i - 1] != 'e' || sentence1[i - 1] != 'i' ||
sentence1[i - 1] != 'o') &&
(sentence2[j - 1] == 'a' || sentence1[i - 1] != 'u' ||
sentence1[i - 1] != 'e' || sentence1[i - 1] != 'i' ||
sentence1[i - 1] != 'o')) {
substitution = 4;
}
if (sentence1[i - 1] == sentence2[j - 1]) {
substitution = 0;
}
if ((sentence1[i - 1] == 'a' || sentence1[i - 1] == 'u' ||
sentence1[i - 1] == 'e' || sentence1[i - 1] == 'i' ||
sentence1[i - 1] == 'o') &&
(sentence2[j - 1] == 'a' || sentence2[j - 1] == 'u' ||
sentence2[j - 1] == 'e' || sentence2[j - 1] == 'i' ||
sentence2[j - 1] == 'o')) {
substitution = 3;
}
if ((sentence1[i - 1] != 'a' || sentence1[i - 1] != 'u' ||
sentence1[i - 1] != 'e' || sentence1[i - 1] != 'i' ||
sentence1[i - 1] != 'o') &&
(sentence2[j - 1] != 'a' || sentence2[j - 1] != 'u' ||
sentence2[j - 1] != 'e' || sentence2[j - 1] != 'i' ||
sentence2[j - 1] != 'o')) {
substitution = 3;
}
cost[i][j] = min(min(cost[i - 1][j] + 2, cost[i][j - 1] + 2),
cost[i - 1][j - 1] + substitution);
}
}
for (i = 0; i < m + 1; i++) {
for (j = 0; j < n + 1; j++) {
cout << cost[i][j] << " ";
}
cout << endl;
}
cout << sentence1[0];
return 0;
}
A condition like: sentence2[j-1]!='a'||sentence2[j-1]!='u' is always true -- no single character can be equal to both a and u, so one of these has to be true.
If you're using !=, it must almost always be joined by &&, not ||, otherwise the result will always be true, regardless of input.

Is there a better way of selecting a random element from an array of variable size than this?

I'm very new to C++ and was wondering if if there is a better way of doing this. It's going to run on an Arduino so I can't use ArrayLists or anything.
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4] = {0,0,0,0};
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[0] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[1] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[2] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[3] = 4;
if (possibleMoves[0] == 0 && possibleMoves[1] == 0 && possibleMoves[2] == 0 && possibleMoves[3] == 0) {
return 0;
}
byte move = 0;
while(move == 0){
move = possibleMoves[random(4)];
}
return move;
}
Thanks,
Joe
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4];
byte index = 0;
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[index++] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[index++] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[index++] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[index++] = 4;
return index ? possibleMoves[random(index)] : 0;
}
You can do yourself a favor and use this:
https://github.com/maniacbug/StandardCplusplus/#readme
Then you can sanitize your code by using standard containers.
Also, there's no ArrayList in C++. That's Java. With the above library, you can use std::vector instead.