Rename line/elements in C - c

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.

Related

C language - Matrix multiplication bug

I'm trying to write a code that gets a matrix A and its dimensions, a matrix B and its dimensions, and returns a matrix C such that C=AB.
It's safe to assume that the number of columns of A is equal to the number of rows of B and so C=AB is defined
This is my code:
int *matrix_multiplication(int *A,int row_A,int column_A,int *B,int row_B,int column_B)
{
int row_C,column_C,*C,i,j,k,sum=0;
row_C=row_A;
column_C=column_B;
C=(int*)malloc(row_C*column_C*sizeof(int));
for(i=0;i<row_C;i++)
{
for(j=0;j<column_C;j++)
{
for(k=0;k<column_A;k++)
sum+=(*(A+column_A*i+k))*(*(B+column_B*k+j));//A[i][k]B[k][j]
*(C+row_C*i+j)=sum;
sum=0;
}
}
return C;
}
A little explanation: I view a matrix as a single dimensional array, of size columns*rows*sizeof(int) and the given formula A[i][j]=*(A+column_A*i+j) where A is pointer to the first element of the array, and column_A is the amount of columns in "matrix" A.
My problem is that my code does not work for some inputs when row_C != column_C
For example, if A=[28,8,12;14,5,45] and B=[31;27;11] it returns C=[1216;-842150451]
Why does this happen? I can't seem to find the bug.
Try
*(C+column_C*i+j)=sum;
it might be an idea to make a function or macro for accessing matrix elements. That way similar problems in the future can be avoided. Better than that make a matrix class with method.

Delete a column from a double array

I'm stuck here. I've got a matrix of size NxN stored in a double array. Then I want to delete a given column, lets say the first column. So I created a new double array of size NxN-1 and copy the values from the first matrix to the second one, except the 1st column of course. But then I want to set the first array to be the second array. I am blanking here.
double matrix[N][N]
//fill up the matrix code here...
// remove first column of array
double newMatrix[N][N-1];
for(i = 0; i < N; i++){
for(j = 1; j < N; j++){
newMatrix[i][j-1] = matrix[i][j];
}
}
matrix = newMatrix; // how do I set this correctly? Do I need to realloc the first array?
You cannot assign arrays in C, which I assume that your compiler tells you. To do such dynamic memory management, you will need to use pointers instead of arrays. I suggest you read up on how malloc() and free() work so that you can do what you want.
Edit:
Another solution comes to mind if you are only removing columns (or rows): keep track of the number of rows and columns used in the array. Then you can remove a row or column within the original array without creating a copy first. Just move the data past the delete column (or row) to the left (or up) then decrement your size counters. (I hope this make sense. If not let me know and I'll elaborate.)
like Code-guru said malloc() and free() should help alot, but if u simply wanted to delete the last column the you wouldn't need two arrays:
double matrix[2][3] = {1,2,3,4,5,6}; //declaring a 2 by 3 matrix
for (i=0;i<2;i++) //rows
{
for (j=0;j<3-1;j++) //columns - 1
{
printf("%.1f ",matrix[i][j]); //I chose to display matrix...
}
printf("\n");
}
Instead of accessing elements from array[i][j], one might opt to access elements from array + stride_x[x] + stride_y[y]; where array is originally introduced as double matrix[N*N]; or double *matrix = malloc(sizeof(double)*N*N);.
The stride_y[x] would originally contain offsets of columns for all rows: 0 1 2 3 4 ... N-1 and stride_y[y] would contain similar offsets multiplied with original row width 0 N 2*N 3*N..
From these 1-D arrays one can more effortlessly delete or exchange complete rows and columns, which may come handy in eg. recursive implementation of determinant calculation / Gauss Jordan elimination.

How should a RPG tile-based map be represented?

I have a tile-based RPG system where a specific tile type is represented by a string (i.e. Grass = "g", Dirt = "d"). The problem is that I do not know how to represent a map (a group of tiles gathered in a specific order) in a way where each tile can be accessed by their x/y coordinates efficiently. Should the maps be represented in array format :
map[0].coords[x][y] = "g";
Or perhaps in some other way?
It depends on what language you are using, but a 2-dimensional array is usually an efficient way to do this.
Accessing elements in an array is usually quick because the position of a given element in memory can be calculated based on the array indexes provided, without having to iterate over other elements. Other data structures, (eg linked lists) are much slower for this type of retrieval.
A few things, dependant on the language:
1: If possible, set constant integers for terrain type. Constants use less memory and are quicker to referance/retrieve, same with integers over strings
2: A two dimensional would probably be the most efficant way of doing it.
An example
CONST(INT) GRASS = 1;
CONST(INT) DIRT = 2;
CONST(INT) SNOW = 3;
// assuming map is an array containing objects, and coords is a 2d
// array of said object:
map[0].coords[x,y] = GRASS;
A two dimensional array is fine.
You can also use a one-dimensional array. Here's a snippet of Java code I have lying around:
char [] cells = new char[WORLD_WIDTH * WORLD_HEIGHT];
public char get(int x, int y) {
return cells[x + y * WORLD_WIDTH];
}
public void set(int x, int y, char c) {
cells[x + y * WORLD_WIDTH] = c;
}
Suppose your world is 10 by 10 tiles, then the first row is in cells[0] to cells[9], the last row in cells[90] to cells[99], and so on.
Of course, you may want to add additional checks to ensure that the x and y parameters are valid.

How to pick a random element in a 2 dimensional array

Ok I want to pick a random point in the 2d array so it can be filled. Ive seen how to do this for a 1d array, and am wondering how this would be possible in a 2d array. All I have seen about this method is that the same position comes up again, which is a slight problem, but I don't know how to do it in the first place. The 2d array is essentially a grid, with the dimensions being the x and y coordinates. And the random element selecting a point within the boundaries (which is user selected but for the purposes of this problem can be 30x50.
EDIT:
import java.util.Random;
class pickRand{
public static String get (int x, int y){
int rndx = generator.nextInt(x) + 2;
int rndy = generator.nextInt(y) + 2;
}
}
So would this work, the x and y will correspond to the user generated number and have a raised boundary of 2 either side to prevent any objects going (partially outside or of the grid. Nothing needs to be returned right?
If you grid is of size M by N
Generate a random number between 0 and M-1 say i
Generate another random between 0 and N-1 say j
(i,j) will be a random element of the 2d array
What role does the array play here?
Essentially, the task is to pick... random integer 2D coordinates.
So if you want two coordinates, say i in 0...W-1 and j in 0...H-1, just draw two random integers. If you need more for higher dimensionality, draw more randoms.
Obviously, you can then access array[i][j].
In most languages, arrays can however be ragged, i.e. the rows/columns may have different lengths. This is however just as trivial to handle...

"Direction" of bidimensional arrays in C

as a C newcomer I'm a bit confused about bidimensional arrays.
If I want to represent a matrix of 3 rows and 5 columns, I guess the correct declaration is:
char a[3][5];
So, is this an array of 3 pointers to 5 arrays of chars or what?
How come whenever I try to cycle through it like the following it seems to read the wrong results?
int x, y;
for( x=0; x<3; x++ ){
for( y=0; y<3; y++ ){
printf( "%c", a[x][y] );
}
}
Are the following equivalent and correct ways to initialize it?
char a[3][5] = {
{1,0,0,0,1},
{1,0,0,0,1},
{1,0,0,0,1},
};
char a[3][5] = {1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1};
Thanks for any eventual upcoming explanation.
EDIT
Sorry the typos, the code is not copied. By the way, I keep on having them read like they where read in a vertical way, not in a horizontal one.
Also in the example in this tutorial http://www.cplusplus.com/doc/tutorial/arrays/ it reads the array in a way that is not streight-forward to me as it seems to work on a 5x3, HeightWidth, yx, colsrows structure instead of a 3x5, WidthHeight, xy. rowscols one:
#define WIDTH 5
#define HEIGHT 3
int jimmy [HEIGHT][WIDTH];
int n,m;
int main ()
{
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
jimmy[n][m]=(n+1)*(m+1);
}
return 0;
}
Just for what it is and what not.
char a[3][5];
There are no pointers involved. A multi dimensional array like that is an array of arrays of .... and so on. In your case, you have an array of 3 arrays of 5 characters. It becomes clearer when you do it with typedefs.
typedef char T[5];
T a[3];
No pointers are involved whatsoever. If you want to access the first array of those 3 ones, you can do so:
a[0];
And it will give you back an object of type char[5]. Normally, you don't notice that because normally you index all dimensions. So the array that's returned by a[0] is subscript by the next index, for example a[0][1]. The [1] will be applied to the array that was returned by a[0], which as we have figured out earlier has type char[5].
So, is this an array of 3 pointers to 5 arrays of chars or what?
Let's create that type and see how it's different to the above. Creating it is simple, once you get the basic declarators:
Creating a pointer: *D
Creating an array: D[N]
D is just an existing another declarator. So now let's go on. First you say array of 3 pointers to 5 arrays of chars.... I think you meant array of 3 pointers to arrays of 5 chars. First, array of 5 is created like
D1[5]
Now, let's replace D1 by a pointer to declarator:
(*D2)[5]
We had to insert parentheses, because the subscript operator [N] binds better than the dereference operator *, and it would otherwise be read as *(D2[5]) which isn't what we want. Now we have pointer to array of 5.
Now let's do the array of 3. Replacing D2 by D3[3] yields this:
(*D3[3])[5]
Great, now we have got a array of 3 pointer to array of 5. Just putting the base type that that declarator appertains to yields the complete declaration:
char (*D3[3])[5];
That's of course a complete different thing :) You could use it to store pointers to your other array which was of type array of 3 arrays of 5 char. Let's store a pointer to the first sub-array of a into D3[0]. We figured out earlier that a[0] has type char[5]. We can store a pointer to that array into D3[0], because D3 is an array of pointers to char[5], what a coincidence!
D3[0] = &a[0]; // works!
I hope this little exercise has shown you some of the relations between pointers and arrays. Cheers!
I see a couple of problems with your code. First (copied from above):
int x, y;
for( x=0; x<3; x++ ){
for( x=0; x<3; x++ ){
printf( a[x][y] );
}
}
In your inner-loop, it looks like you want to use y instead of x, and you want y to go from 0..5. Currently, you are repeating the variable x. Also, you have a problem with your printf() statement. Here's some corrected code:
int x, y;
for( x=0; x<3; x++ ){
for( y=0; y<5; y++ ){
printf("%d\n", a[x][y] );
}
}
Second, when you initialize your array, your code is almost correct. Here's the corrected version:
char a[3][5] = {
{1,0,0,0,1},
{1,0,0,0,1},
{1,0,0,0,1}
};
(I removed the , after the very last "row" of data - that was a syntax error.)
The 2nd syntax you posted is incorrect (the one with no curly braces).
You've got wrong results because you're using x twice (looks like a copy/paste error). Try
int x, y;
for (x = 0; x < 3; x++) {
for (y = 0; y < 5; y++) {
printf("%c", a[x][y]); // Emil H says "%d" might be more useful
}
}
Edit: I'm not sure what's confusing about that tutorial. It's precisely equivalent to your code, except instead of printing the array, it's setting each element to (row*column) (where both row and column are one-based, hence the +1's).
The image that is in the tutorial is a great representation of the data:
alt text http://www.cplusplus.com/doc/tutorial/arrays/bidimensional_arrays3.gif
From the example, the nested for loops traverses across (left -> right) the array row by row and fills in a value for each column.
The small errors like using "%c" when you probably want "%d" and such are not what you really want to get answered I humbly think. You say you are a bit confused about arrays and also mentions that you expect to see pointers as the array-elements of the array containing arrays. You
The last comma in your definition of the array-of-arrays is NOT a syntax error. It is permitted as of C99.
What really will clear up things is to know that arrays are not pointers. It is true that an array name may be used as a constant pointer (to the first element) and that pointers can be indexed like they were arrays. This does not mean, however, that arrays and pointers are the same. They are not.
You ask about what the symbol "a" in your program actually is. It is an array of arrays. The memory layout may be visualized like a long line cut in three parts but still on a continuous line. Then cut each of these in five parts in the same manner. When addressing one element you must use two indexes; first for which five-element-array you want and then for which fifth of this element you want.
The memory layout is not like a grid of rows and columns. The memory is addressed by one scalar, so its linear. Pointer arithmetic may be the next thing you could look into, and see how an increment on a pointer works.
int x, y;
for( x=0; x<3; x++ ){
for( x=0; x<3; x++ ){
printf( a[x][y] );
}
}
You need to change the 2nd for loop to refer to 'y' instead of 'x'.
hope that helps.
You're using printf in the wrong way. Try:
printf("%d", a[x][y]);
I'm not sure whether you'll want to use %c or %d. If you want to print the number, use %d. If you want to print an actual character, use %c.
char a[3][5];
So, is this an array of 3 pointers to
5 arrays of chars or what?
Yes, that's what it is. Although you could also manipulate it as a consecutive set of 15 chars.
By convention, most people would think of it as representing a matrix with 3 rows and 5 columns (I think), but there's nothing about the data structure itself that requires that. You could just as easily use it to represent 5 rows and 3 columns. Or 3 sets that each include 5 elements but have no meaningful relationship to each other at all.
A particular library for doing matrix manipulation would have a convention for this.

Resources