create a matrix with condition in C++ - c++

I want to create a matrix B from a matrix A, in C++.
First column of A is distance D1, second column is distance D2. Matrix B copies the same columns (and rows) of A, except when in A it happens that D2-D1=delta exceeds a threshold. In this case, the row of A is break in two rows in B.
I wrote an algorithm, but the problem is that it gives segmentation fault. Someone can help, why it happens?
std::vector<float> newD1(10), newD2(10);
float box=5.;
int j=0;
for(auto i=0;i<D1.size();i++){
float delta=D2[i]-D1[i];
if (delta>box){ //break row i in two rows: j and j+1
//first half of row i goes in row j
newD1[j]=D1[i];
newD2[j]=(D1[i]+D2[i])/2.;
//second half of row i goes in j+1
D1[j+1]=(D1[i]+D2[i])/2.;
D2[j+1]=D2[i];
j=j+2; //we skip two row because we break up the original row in 2 rows
}
else{
newD1[j]=(D1[i]);
newD2[j]=D2[i];
j=j+1; //we skip one row because the original row is unchanged
}
}
Here I give you an example of matrix A and B; I also specify delta beside each line of the matrix.
Matrix A:
#D1 D2 delta
|0 5 | 5
A= |5 15 | 10 }--> exceed the threshold, delta>5. Must break in 2 rows in `B`
|15 17 | 2
B is created breaking the second line in two lines, because delta>5 :
#D1 D2 delta
|0 5 | 5
B= |5 10 | 5 }--> created from row #2 of `A`. `D2` is midpoint between`D1` and `D2` in row #2 in `A`
|10 15 | 5 }--> created from row #2 of `A`. `D1` is midpoint between`D1` and `D2` in row #2 in `A`
|15 17 | 2
EDIT:
What if I want to recursively break up the rows (e.g. suppose that at row #2 in A, delta>3*box, meaning that I need to break up that row in 3 rows in B). Any suggestions?

1.You can use push_back to avoid the size definition
2.You updated D1 and D2 instead of newD1 and newD2
#include <vector>
#include <iostream>
using namespace std;
int main()
{
std::vector<float> D1 = { 0,5,15 };
std::vector<float> D2 = { 5,15,17 };
std::vector<float> newD1, newD2;
float box = 5.;
for (auto i = 0; i < D1.size(); i++) {
float delta = D2[i] - D1[i];
if (delta > box) { //break row i in two rows: j and j+1
//first half of row i goes in row j
newD1.push_back(D1[i]);
newD2.push_back((D1[i] + D2[i]) / 2.);
//second half of row i goes in j+1
newD1.push_back ((D1[i] + D2[i]) / 2.);
newD2.push_back (D2[i]);
}
else {
newD1.push_back(D1[i]);
newD2.push_back(D2[i]);
}
}
}

Related

Shift matrix columns/rows in all directions c++

I have a 2d vector that looks like this:
a b c
d f g // actual size is 32 x 32
h i j
And I want to shift the rows/columns:
d f g h i j b c a c a b
h i j <-- up a b c <-- down f g d <-- left g d f <-- right
a b c d f g i j h j h i
In python I can accomplish all of those in nifty one liners, such as matrix = [row[-1:] + row[:-1] for row in matrix] to move the columns to the right. But, c++ doesn't use the handy : in list indexes or negative indexes. Well, not negative indexes like in python at least.
Anyway, I'm looking for a good way to do this. I've seen lots of other SO questions about swapping rows, or rotating, but none I have seen have solved my problem.
Here's my first take on moving columns to the right:
vector<vector<string>> matrix{{"a","b","c"}, {"d","e","f"}, {"g","h","i"}};
for (int i = 0; i < matrix.size(); i++)
{
vector<string> col{matrix[i][2], matrix[i][0], matrix[i][1]};
matrix[i] = col;
}
This works, but will be very long once I write all 32 indexes. I was hoping someone could point me to something shorter and more flexible. Thanks!
EDIT: For future viewers (taken from G. Sliepen's answer) :
vector<vector<string>> matrix{{"a","b","c"}, {"d","e","f"}, {"g","h","i"}}; // or can be ints
rotate(matrix.begin(), matrix.begin() + 1, matrix.end()); // move rows up
rotate(matrix.begin(), matrix.begin() + matrix.size() - 1, matrix.end()); // move rows down
for (auto &row: matrix) // move columns to the left
{
rotate(row.begin(), row.begin() + 1, row.end());
}
for (auto &row: matrix) // move columns to the right
{
rotate(row.begin(), row.begin() + row.size() - 1, row.end());
}
There is std::rotate() that can do this for you. To rotate the contents of each row:
vector<vector<string>> matrix{{"a","b","c"}, {"d","e","f"}, {"g","h","i"}};
for (auto &row: matrix)
{
std::rotate(row.begin(), row.begin() + 1, row.end());
}
To rotate the contents of the columns, you just rotate the outer vector:
std::rotate(matrix.begin(), matrix.begin() + 1, matrix.end());

Filling a 2*n room with two different tiles

I came across a problem where I have to fill a rectangle having 2 rows and n columns. There are two tiles one 1*2 tile and second a L shaped tile of larger sides having dimension 2 units and smaller sides having dimension 1 units.
I solved it through dynamic programming and am not pretty sure if it is working all right or not. If not what will be the correct bottom up code of this problem.
Below is the function snippet of my solution.
For the recurrence one column can be filled in one way putting the first tile vertically two adjacent columns can be filled in one way by putting the first type of tile horizontally one after the other. Three adjacent columns can be filled by aligning the two L-shaped in an inverted manner in 2 ways and four adjacent columns can be filled by two L-shape tile facing each other and the first type of tile lying horizontally in 2 ways.
int tileways(int n) //n=no.of columns of the rectangle.
{
int i;
int a[n+4];
a[0]=0;
a[1]=0;
a[2]=0;
a[3]=1;
for(i=4;i<n+4;i++)
{
a[i]=a[i-1]+a[i-2]+2*a[i-3]+2*a[i-4];
}
return a[n+3];
}
Using approach from my first comment.
l[3] configuration:
L[3] configurations:
#include <iostream>
using namespace std;
int tileways(int n) //n=no.of columns of the rectangle.
{
int l[20];//straight border
int L[20];//extra square
l[0] = 1;
l[1] = 1;
L[0] = 0;
L[1] = 1;
for (int i = 2; i <=n; i++) {
l[i] = l[i-1] + l[i-2] + 2*L[i-2];
//add | to the last straight, = to the 2nd last straight,
//two cases of L to extra
L[i] = l[i-1] + L[i-1];
//add L to the last straight, - to the extra
}
return l[n];
}
int main() {
for (int i = 1; i < 10; i++)
std::cout<<i<<" "<< tileways(i)<<std::endl;
return 0;
}
ideone result
1 1
2 2
3 5
4 11
5 24
6 53
7 117
8 258
9 569
For reference: OEIS sequence number of possible tilings of a 2 X n board, using dominos and L-shaped trominos.
1, 2, 5, 11, 24, 53, 117, 258

Euclidean distance between each record with other records in an array

so i have an array [nm] and i need to code in c++ the Euclidean distance between each row and the other rows in the array and store it in a new distance-array [nn] which every cell's value is the distance between the intersected rows.
distance-array:
r0 r1 .....rn
r0 0
r1 0
. 0
. 0
rn 0
the Euclidean distance between tow rows or tow records is:
assume we have these tow records:
r0: 1 8 7
r1: 2 5 3
r2
.
.
rn
Euclidean distance between r0 and r1 = sqrt((1-2)^2+(8-5)^2+(7-3)^2)
to code this i used 4 loops(which i think is too much) but i couldn't do it right, can someone help me to code this without using 3-D array ??
this is my code:
int norarr1[row][column] = { 1,1,1,2,2,2,3,3,3 };
int i = 0; int j = 0; int k = 0; int l = 0;
for (i = 0; i < column; i++){
for(j = 0; j < column; j++){
sumd = 0;
for (k = 0; k < row; k++) {
for (l = 0; l < row; l++) {
dist = sqrt((norarr1[i][k] - norarr1[j][l]) ^ 2);
sumd = sumd + dist;
cout << "sumd =" << sumd << " ";
}
cout << endl;
}
disarr[j][i] = sumd;
disarr[i][j] = sumd;
cout << disarr[i][j];
}
cout << endl;
}
There are several problems with your code. For now, let's ignore the for loops. We'll get to that later.
The first thing is that ^ is the bitwise exclusive or (XOR) operator. It does not do exponentiation like in some other languages. Instead, you need to use std::pow().
Second, you are summing square roots, which is not the correct way to calculate Euclidean distance. Instead, you need to calculate a sum and then take the square root.
Now let's think about the for loops. Assume that you already know which two rows you want to calculate the distance between. Call these r1 and r2. Now you just need to pair one coordinate from r1 with one coordinate from r2. Note that these coordinates will always be in the same column. This means that you only need one loop to calculate the squares of the differences of each pair of coordinates. Then you sum these squares. Finally after this single loop you take the square root.
With that out of the way, we need to iterate over the rows to choose each r1 and r2. Okay, this will take two loops since we want each of these to take on the value of each row.
In total, we will need three for loops. You can make this easier to understand by designing your code well. For example, you can create a class or struct that holds each row. If you know that every row is only three dimensions, then create a point or vector3 class. Now you can write a function which calculates the distance between two points. Finally, store the list of points as a 1D array. In fact, breaking up the data and calculation in this way makes the previous discussion about calculating the distance even easier to understand.

C++ Nested for loops

I am writing a program that modifies data in a csv file.
In the csv file, the COLUMNS are organized as follows..
X-coordinate, Y-coordinate, Z-coordinate, info, X, Y, Z, info, X, Y, Z info..
The first X-coordinate begins in column 4 and the next one is 4 columns after, in 8. For Y, it's column 5 and column 9, so on. Since I saved the data onto a deque, the first ones correspond to data[row#][3] for x, and y would be data[row#][5].
for(int k=0; k<618; k++) { //all rows 618
for(int l=3; l<96; l=l+4) { //x columns
for(int m=4; m<97; m=m+4) { //y columns
data[k][l] = (data[k][l] )*(data[k][2]) + (data[k][m])*(data[k][1]);
In the calculation in the loop, I want it to replace all the x values (l) in columns (k) with the value I get from this equation (as I created for the loop)
x' = x* cos(theta) + y* sin(theta)
the values for cos(theta) and sin(theta) are found in columns 2 and 3 for all the rows (hence, data[k][2] and data[k][1].
Unfortunately, in testing this out with several cout statements, I noticed it is not doing as desired.
DESIRED BEHAVIOR OF LOOP:
1st time through loop: Calculation is done for row 1, x = value inside column 4 and y= value in col.5
*end of loop iteration, re-start, k, l, and m get updated to 2,9,10.
Calculation in the loop is executed for these new values, so on.
Main issue is k, l, m are not all three being updated as desired after the data[k][l] line What could be causing this?
Thank you.
You do not understand nested loops.
What you intend is something like this:
for(int k=0; k<618; k++) { //all rows 618
for(int n=0; n<24; ++n) { //groups
l = 4*n + 3;
m = 4*n + 4
data[k][l] = (data[k][l] )*(data[k][2]) + (data[k][m])*(data[k][1]);
}
}

How to map the indexes of a matrix to a 1-dimensional array (C++)?

I have an 8x8 matrix, like this:
char matrix[8][8];
Also, I have an array of 64 elements, like this:
char array[64];
Then I have drawn the matrix as a table, and filled the cells with numbers, each number being incremented from left to right, top to bottom.
If I have, say, indexes 3 (column) and 4 (row) into the matrix, I know that it corresponds to the element at position 35 in the array, as it can be seen in the table that I've drawn. I believe there is some sort of formula to translate the 2 indexes of the matrix into a single index of the array, but I can't figure out what it is.
Any ideas?
The way most languages store multi-dimensional arrays is by doing a conversion like the following:
If matrix has size, n (rows) by m (columns), and we're using "row-major ordering" (where we count along the rows first) then:
matrix[ i ][ j ] = array[ i*m + j ].
Here i goes from 0 to (n-1) and j from 0 to (m-1).
So it's just like a number system of base 'm'. Note that the size of the last dimension (here the number of rows) doesn't matter.
For a conceptual understanding, think of a (3x5) matrix with 'i' as the row number, and 'j' as the column number. If you start numbering from i,j = (0,0) --> 0. For 'row-major' ordering (like this), the layout looks like:
|-------- 5 ---------|
Row ______________________ _ _
0 |0 1 2 3 4 | |
1 |5 6 7 8 9 | 3
2 |10 11 12 13 14| _|_
|______________________|
Column 0 1 2 3 4
As you move along the row (i.e. increase the column number), you just start counting up, so the Array indices are 0,1,2.... When you get to the second row, you already have 5 entries, so you start with indices 1*5 + 0,1,2.... On the third row, you have 2*5 entries already, thus the indices are 2*5 + 0,1,2....
For higher dimension, this idea generalizes, i.e. for a 3D matrix L by N by M:
matrix[ i ][ j ][ k ] = array[ i*(N*M) + j*M + k ]
and so on.
For a really good explanation, see: http://www.cplusplus.com/doc/tutorial/arrays/; or for some more technical aspects: http://en.wikipedia.org/wiki/Row-major_order
For row-major ordering, I believe the statement matrix[ i ][ j ] = array[ i*n + j ] is wrong.
The offset should be offset = (row * NUMCOLS) + column.
Your statement results to be row * NUMROWS + column, which is wrong.
The links you provided give a correct explanation.
Something like this?
//columns = amount of columns, x = column, y = row
var calculateIndex = function(columns, x, y){
return y * columns + x;
};
The example below converts an index back to x and y coordinates.
//i = index, x = amount of columns, y = amount of rows
var calculateCoordinates = function(index, columns, rows){
//for each row
for(var i=0; i<rows; i++){
//check if the index parameter is in the row
if(index < (columns * i) + columns && index >= columns * i){
//return x, y
return [index - columns * i, i];
}
}
return null;
};