I'm programming in C and I need some help:
I' have a bidimensional vector ( n rows, 2 columns) and each rows represent the coordinates of an Element I want to put in a bigger bidimensional vector, something like battleship. Is it possible to give a name to each rows? For example, how can I give the name X to the first element of my smaller vector?
What I've to do is: the element in vector represents coordinate of an element in a bigger vector, so each rows represent an element. I compare to at once, and if their are neighbors and one of them is "X", also the other one become an "X" element.
Something like that:
enter code here
int x,y;
for(int a=0; a<nbE; a++)
{
for(int i=1; i<n;i++)
{
x=vector[a][0]-vector[i][0];
if((x==1)||(x==-1)||(x==0))
{
y=vector[a][1]-vector[i][1];
if( (y==1)||(y==-1)||(y==0))
{
if (vector[a]="X") *That's the point*
vector[i]="X";
}
}
}
.......
}
In C this is not directly possible, however.
A tricky (thus not recommended) approach does exist:
#define X (vector[0][0])
Now you're able to use X anywhere to resemble vector[0][0].
If you migrate your project to C++ then reference will be available, providing a natural way to do so.
I am facing a problem in lazy propagation of segment tree.
I have an array A, of length N ,of smaller arrays (of max length 20).
I also have an array of indices B, referring to the index i am currently pointing to in the array Ai.
There are 2 operations,:
a) update the pointers of B for a given range to point to the next element.
b) print the max of the values the pointers are currently pointing to in the given range.
for example:-
int[][] array=
{
{1,2,3,4},
{8,4,0,0},
{3,4,2,5}
};
int[] B={1,1,1};
On making a query for range 1,2 max is 8.
This is because the pointers of array B are pointing to the first elements of the array.So we are working with 1,8.
On making a query of 2,3 max =8;
this is because we are working with the values 8,3.
In general,
int max(int[][] arr,int[] b,int l,int r){
int max=0;
for(int i=l;i<=r;i++){
max=Math.max(max,arr[i][b[i]]);//using java Math class here
}
return max;
}
void update(int[] b,int l,int r){
for(int i=l;i<=r;i++){
b[i]++;
}
}
These are the two methods in a very simple form.
However ,due to large input constraints, i need a O(logn) query and update time.That is why i thought of using segment trees(currently it's complexity is O(n^2).However I cannot seem to figure out how to update the intermediate nodes in lazy propagation.
Any insight will be helpful.
Also, if you could link any similar problem online, it would be really helpful as I could not(I do not know of any such as this is not from any website).
Thank you for any help.
NOTE : If b[i]>a[i].length then replace a[i][b[i]] with 1.
I wrote a code and I have some data stored in a 2d matrix:
double y[LENGTH][2];
I have a function that take as input a 1D array:
double function(double* data)
I am interested in passing the data stored in the first column of this matrix to this function. How can I do that using pointers?
My function is something like (where the array data is an array of double containing LENGTH elements:
double data[LENGTH];
):
double function(double* data){
double result=0;
for(int i=0; i<LENGTH; i++){
result+=data[i];
}
return result;
}
And I want to pass to this function a row of a matrix as data input.
Thanks to everyone in advance!
If you pass a pointer to the first element of your 2D matrix, you can access it as a 1 D matrix since the elements are stored contiguously:
double y[LENGTH][2];
x = function(y[0]);
...
double function(double* p) {
int ii;
double sum=0;
for(ii=0; ii<2*LENGTH; ii++) sum += p[ii];
return sum;
}
Note that in this case the order of accessing the elements is
y[0][0]
y[0][1]
y[1][0]
y[1][1]
y[2][0]
... etc
update - you just clarified your question a little bit. If you want to access just one column of data, you need to skip through the array. This means you need to know the size of the second dimension. I would recommend something like this:
double function(double* p, int D2) {
int ii;
double sum=0;
for(ii=0; ii<D2*LENGTH; ii+=D2) sum += p[ii];
return sum;
}
And you would call it with
x = function(y[colNum], numCols);
Now we start at a certain location, then, skip forward D2 elements to access the next element in the column.
I have to say that this is rather ugly - this is not really how C is intended to be used. I would recommend wrapping things into a class that handles these things for you cleanly - in other words, switch to C++ (although it's possible to write pure C functions that "hide" some of this complexity). You could of course copy the data to another memory block to make it contiguous, but that's usually considered a last recourse.
Be careful that you don't end up with code that is unreadable / unmaintainable...
further update
Per your comment, the above is still not what you wanted. Then I recommend the following:
double *colPointer(double *p, int rowCount, int colCount) {
double *cp;
int ii;
cp = malloc(rowCount * sizeof *cp);
for(ii=0; ii<rowCount; ii++) cp[ii] = *(p + ii * colCount);
return cp;
}
This will return a pointer to a newly created copy of the column. You call it with
double *cc;
cc = colPointer(y[colNum], LENGTH, 2);
answer = function(cc);
And now you can use cc in the way you wanted. If you have to do this many times you might be better off transposing the entire array just once - that way you can pass a pointer to a row of the transpose and achieve your result. You can adapt the code above to generate such a transpose.
Note that there is a risk of memory leaks if you don't clean up after yourself with this method.
the question is that do you consider to be the row-dimension.
usually the first one is rows and the second one cols.
that means that your double y[LENGTH][2]; is a matrix with LENGTH rows ans 2 cols.
if that is also your interpretation then the answer to your question is "you can't" since the memory is layed out like this:
r0c0 r0c1 r1c0 r1c1 r2c0 r2c1 ...
you can retrieve pointer to a row but not to a column.
matrix classes are usually designed in a way, that row and column step length is stored so that by carefully setting them you can build sub matrices on a big data chunk.
you may look for opencv matrix implementation if you plan to perform complexer tasks.
if you can change the implementation of the function you want to call. you can change it to accept the row step (number of your columns), so that it does not joust increment the pointer by one to reach the next element but to increment the pointer by row step.
as an alternative there is the obvious way to copy the required column to a new array.
edit:
fixed stupid error on memory layout diagram
I have an interesting problem, which I have been struggling with for the past 2 days without a concrete solution.
I am attempting to write a program in C which takes the following input array:
1,1,5,5,
1,1,5,9,
2,2,6,2,
1,2,5,5,
1,3,6,6,
1,4,5,1,
4,1,5,6,
5,2,7,1,
1,1,6,0,
2,2,5,0,
step1: group the above array based on the 3rd column like this (bucket sort on tuple of 4 elements (i.e. each row), based on values of 3rd column:
2,2,5,5
1,1,5,9,
1,2,5,5,
1,4,5,1,
4,1,5,6,
2,2,5,0,
2,2,6,2,
1,3,6,6,
1,1,6,0,
5,2,7,1
Step 2: Finally sort the elements based on the 4th column within each bucket like this:
Final Output Array:
2,2,5,0,
1,4,5,1,
2,2,5,5,
1,2,5,5,
4,1,5,6,
1,1,5,9,
1,1,6,0,
2,2,6,2,
1,3,6,6,
5,2,7,1
The elements in the 1st and 2nd column do not play any role in the above sorting process.
I have tried various techniques, using quicksort or bucket sort followed by a subsequent quicksort. Nothing has worked out quite right.
Could anyone suggest a method of doing this in C, using appropriate data structures.
The thing is, you don't really need to do multiple sorts; you can do a single sort based on two fields of your tuple.
Just use an existing sort algorithm, but with a comparing function which looks like this:
if (val[2] != otherval[2])
return val[2] < otherval[2];
else
return val[3] < otherval[3];
This will use the third column to sort, unless the values are equal, in which case it will use the fourth.
Or if you want to do two separate sorts, FIRST sort by the fourth column, THEN by the third.
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *x, const void *y){
int (*a)[4] = (int(*)[4])x;
int (*b)[4] = (int(*)[4])y;
if((*a)[2]==(*b)[2])
return (*a)[3] - (*b)[3];
else
return (*a)[2] - (*b)[2];
}
int main(void){
int data[][4] = {
{1,1,5,5},
{1,1,5,9},
{2,2,6,2},
{1,2,5,5},
{1,3,6,6},
{1,4,5,1},
{4,1,5,6},
{5,2,7,1},
{1,1,6,0},
{2,2,5,0}
};
int size = sizeof(data)/sizeof(data[0]);
int i,j;
qsort(data, size, sizeof(data[0]), cmp);
//result print
for(i=0;i<size;++i){
for(j=0;j<4;++j)
printf("%d ", data[i][j]);
printf("\n");
}
return 0;
}
This should actually be pretty simple to do. The standard qsort function takes a call back which compares two elements. Just write your callback to expect the elements to be the subarrays and compare first using the Third element. If the third elements are equal then compare using the fourth element.
I created a sparse matrix in MEX using mxCreateSparse.
mxArray *W;
W=mxCreateSparse(n*n,n*n,xsize,mxREAL);
double *wpoint;
wpoint=mxGetPr(W);
for(p=0;p<xsize;p++)
{
Wpoint[(returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1]))]= exp(-df[p]/(SIGMAI*SIGMAI)) * exp(-dx[p]/(SIGMAJ*SIGMAJ));
}
the maximum value which comes from (returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1])) is n*n*n*n and I have created the sparse matrix of dimension (n*n)X(n*n)
When I display the whole matrix, some of the zero elements come as junk.
Also for large values of n, segmentation fault occurs at wpoint.
The pr array holds xsize elements and you accessing the array with out of bounds indices . Hence the seg violation.
I think your fundamental problem is that you have not fully grasped how sparse matrices are stored in MATLAB. I'm not an expert on the MATLAB implementation details but my recollection is that it uses compressed column storage.
In essence there are 3 arrays as follows:
double pr[NZMAX] which contains the NZMAX non-zero values.
int ir[NZMAX] which contains the row number of each value in pr.
int jc[m] which indexes into pr and ir identifying the first item in each of the m columns.
That's the executive summary, but I recommend that you read up on the details more carefully.