Copying a subset of an array into another array / array slicing in C - c

In C, is there any built-in array slicing mechanism?
Like in Matlab for example,
A(1:4)
would produce =
1 1 1 1
How can I achieve this in C?
I tried looking, but the closest I could find is this: http://cboard.cprogramming.com/c-programming/95772-how-do-array-subsets.html
subsetArray = &bigArray[someIndex]
But this does not exactly return the sliced array, instead pointer to the first element of the sliced array...
Many thanks

Doing that in std C is not possible. You have to do it yourself.
If you have a string, you can use string.h library who takes care of that, but for integers there's no library that I know.
Besides that, after having what you have, the point from where you want to start your subset, is actually easy to implement.
Assuming you know the size of your 'main' array and that is an integer array, you can do this:
subset = malloc((arraySize-i)*sizeof(int)); //Where i is the place you want to start your subset.
for(j=i;j<arraySize;j++)
subset[j] = originalArray[j];
Hope this helps.

Thanks everyone for pointing out that there is no such built-in mechanism in C.
I tried using what #Afonso Tsukamoto suggested but I realized I needed a solution for multi-dimensional array. So I ended up writing my own function. I will put it in here in case anyone else is looking for similar answer:
void GetSlicedMultiArray4Col(int A[][4], int mrow, int mcol, int B[1][4], int sliced_mrow)
{
int row, col;
sliced_mrow = sliced_mrow - 1; //cause in C, index starts from 0
for(row=0; row < mrow; row++)
{
for (col=0; col < mcol; col++)
{
if (row==sliced_mrow) B[0][col]=A[row][col];
}
}
}
So A is my input (original array) and B is my output (the sliced array).
I call the function like this:
GetSlicedMultiArray4Col(A, A_rows, A_cols, B, target_row);
For example:
int A[][4] = {{1,2,3,4},{1,1,1,1},{3,3,3,3}};
int A_rows = 3;
int A_cols = 4;
int B[1][4]; //my subset
int target_row = 1;
GetSlicedMultiArray4Col(A, A_rows, A_cols, B, target_row);
This will produce a result (multidimensional array B[1][4]) that in Matlab is equal to the result of A(target_row,1:4).
I am new to C so please correct me if I'm wrong or if this code can be made better... thanks again :)

In C,as far as I know, array name is just regarded as a const pointer. So you never know the size of the subset. And also you can assign a arrary to a new address. So you can simply use a pointer instead. But you should manage the size of the subset yourself.

Related

Getting data in rows from a 2D array in C/Objective C

It's quite a simple question, yet I cannot find an answer that works.
Take the following 2D array: int grid[4][4]. I could fill it with integers, so that visually, it could look something like:
1,0,0,5,0 0,0,0,6,7 3,0,0,0,7 2,0,0,0,9 4,0,0,2,0 (each segment a new row)
Now, what if I only wanted the data of one row, to be given as a standard array? The way I would of thought to do this would be: grid[0], which would give me 1,0,0,5,0.
However, this does not seem to work. Can anyone tell me how I can extract rows of data? Here is a code example
int grid[4][4];
//Add in some numbers, e.g.
grid[0][3] = 5;
//Get the first row
int* row1 = grid[0]; //I'm not sure about this
For instance, this example should set "row1" to "0,0,0,5,0"
I have the feeling I'm doing something awfully wrong here...
There is no error message, but it just gives "row1" a random string of integers instead, which are definitely not correct.
Remember, in an array declared int grid[4][4], you can only store four lots of four elements (sixteen total).
Your array, { 1,0,0,5,0 }, { 0,0,0,6,7 }, { 3,0,0,0,7 }, { 2,0,0,0,9 }, { 4,0,0,2,0 } is actually an int [5][5].
What you're doing is not wrong; row1 will be a pointer to the first item of grid[0]. If you wanted to print each element, that's a good start...
In a moment of clarity, you'll likely realise when I mention the word "loop"... You then need a "loop" to loop through each element of the row!
int *row = grid[0];
for (size_t x = 0; x < sizeof grid[0] / sizeof grid[0][0]; x++) {
printf("%d, ", row[x]);
}
putchar('\n');

Best solution to represent Data[i,j] in c?

There is a pseudocode that I want to implement in C. But I am in doubt on how to implement a part of it. The psuedocode is:
for every pair of states qi, and qj, i<j, do
D[i,j] := 0
S[i,j] := notzero
end for
i and j, in qi and qj are subscripts.
how do I represent D[i,J] or S[i,j]. which data structure to use so that its simple and fast.
You can use something like
int length= 10;
int i =0, j= 0;
int res1[10][10] = {0, }; //index is based on "length" value
int res2[10][10] = {0, }; //index is based on "length" value
and then
for (i =0; i < length; i++)
{
for (j =0; j < length; j++)
{
res1[i][j] = 0;
res2[i][j] = 1;//notzero
}
}
Here D[i,j] and S[i,j] are represented by res1[10][10] and res2[10][10], respectively. These are called two-dimentional array.
I guess struct will be your friend here depending on what you actually want to work with.
Struct would be fine if, say, pair of states creates some kind of entity.
Otherwise You could use two-dimensional array.
After accept answer.
Depending on coding goals and platform, to get "simple and fast" using a pointer to pointer to a number may be faster then a 2-D array in C.
// 2-D array
double x[MAX_ROW][MAX_COL];
// Code computes the address in `x`, often involving a i*MAX_COL, if not in a loop.
// Slower when multiplication is expensive and random array access occurs.
x[i][j] = f();
// pointer to pointer of double
double **y = calloc(MAX_ROW, sizeof *y);
for (i=0; i<MAX_ROW; i++) y[i] = calloc(MAX_COL, sizeof *(y[i]));
// Code computes the address in `y` by a lookup of y[i]
y[i][j] = f();
Flexibility
The first data type is easy print(x), when the array size is fixed, but becomes challenging otherwise.
The 2nd data type is easy print(y, rows, columns), when the array size is variable and of course works well with fixed.
The 2nd data type also row swapping simply by swapping pointers.
So if code is using a fixed array size, use double x[MAX_ROW][MAX_COL], otherwise recommend double **y. YMMV

C extract an array from a matrix using pointers

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

C - How can I sort and print an array in a method but have the prior unsorted array not be affected

This is for a Deal or No Deal game.
So in my main function I'm calling my casesort method as such:
casesort(cases);
My method looks like this, I already realize it's not the most efficient sort but I'm going with what I know:
void casesort(float cases[10])
{
int i;
int j;
float tmp;
float zero = 0.00;
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
if (cases[i] < cases[j])
{
tmp = cases[i];
cases[i] = cases[j];
cases[j] = tmp;
}
}
}
//Print out box money amounts
printf("\n\nHidden Amounts: ");
for (i = 0; i < 10; i++)
{
if (cases[i] != zero)
printf("[$%.2f] ", cases[i]);
}
}
So when I get back to my main it turns out the array is sorted. I thought void would prevent the method returning a sorted array. I need to print out actual case numbers, I do this by just skipping over any case that is populated with a 0.00. But after the first round of case picks I get "5, 6, 7, 8, 9, 10" printing out back in my MAIN. I need it to print the cases according to what has been picked. I feel like it's a simple fix, its just that my knowledge of the specifics of C is still growing. Any ideas?
Return type void has nothing to do with prevention of array from being sorted. It just says that function does not return anything.
You see that the passed array itself is affected because an array decays to a pointer when passed to a function. Make a copy of the array and then pass it. That way you have the original list.
In C, arrays are passed by reference. i.e. they're passed as pointer to the first element. So when you pass cases into your function, you're actually giving it the original array to modify. Try creating a copy and sorting the copy rather than the actual array. Creating a copy wouldn't be bad as you have only 10 floats.
Instead of rolling your own sort, consider using qsort() or std::sort() if you are actually using c++
There are 2 obvious solutions. 1) Make a copy of the array and sort the copy (easy, waste some memory, likely not a problem these days). 2) Create a parallel array of integers and perform an index sort, i.e., instead of sorting thing original, you sort the index and then dereference the array using the index when you want the sorted version, otherwise by the raw unsorted array.
Well, make a local copy of you input and sort it. Something like this:
void casesort(float cases[10])
{
float localCases[10];
memcopy(localCases, cases, sizeof(cases));
...
Then use localCases to do your sorting.
If you don't want the array contents to be affected, then you'll have to create a copy of the array and pass that to your sorting routine (or create the copy within the routine itself).
Arrays Are Differentâ„¢ in C; see my answer here for a more detailed explanation.

Test for first empty value of array

Is there anyway to test for the first empty value of a 2 dimensional int array in c?
In my current program, I used 2 for loops before the main program(while loop) to set all the values of my 2 dimensional array to -9999. Then inside my main while loop, I test for the first -9999 value and set it to a value, and then use break to exit from it.
Using this I managed to do my assignment, but I'm not very satisfied, as I think there might be a better solution.
Is there one?
EDIT: Code since you asked for it.
For loop outside while loop:
for(int x=0;x<ctr-1;x++)
{
for(int y=0;y<maxtrips;y++)
{
EmployeeKilos[x][y] = -9999; // Set all the kilos to -9999 to signify emptiness.
}
}
Inside my main while loop:
for(int x=0;x<ctr-1;x++) // and set it to the log kilometers
{
if(employeenames[x].EmployeeNumber == log.Record)
{
for(int y=0;y<maxtrips;y++)
{
if(EmployeeKilos[x][y] == -9999)
{
EmployeeKilos[x][y] = log.Kilometers;
break;
}
}
}
}
All my code: http://pastebin.com/Zb60mym8
As Dave said, checking for empty values cannot be made more efficient than linear time (O(n)), but my answer focuses on a solution that can prevent having to look for it in the first place.
In general you could iterate the matrix in row-major or column-major mode.
Effectively, you can use a single index that translates to a matrix cell like so
for (size_t i=0; i<ROWS*COLS; ++i)
{
int row = i / ROWS;
int col = i % ROWS;
// work with matrix[row][col]
}
This way you could just store and remember the value of i where you last found the first empty cell, so you don't have to restart from the beginning.
If you're not actually interested in row/col addressing, you could forget about those and just use an output iterator to track your current output location.
Here's a demo using 'iterator' style (borrowing from c++ but perfectly C99)
typedef int data;
typedef data* output;
output add_next(data matrix[ROWS][COLS], output startpoint, data somevalue)
{
if (output < (matrix + ROWS*COLS))
*(output++) = somevalue;
return output;
}
Now you can just say:
add_next(matrix, 42);
add_next(matrix, 9);
NOTE the output iterator thing assumes contiguous storage and therefore cannot be used with so-called jagged arrays
HTH
You can use memset to initialise arrays to a fixed value - it's a bit more efficient and cleaner looking than iterating over the array.
Checking for your 'empty' value can't be done much faster than you are doing it, though. :)
This sounds like you should think about your datatype. Since you are already using structs. why don't you add another int for the last unassigned value so you just loop to it. something like
e.g:
struct t_EmployeeKilos{
int kilos[maxtrips];
int nlast;
} EmployeeKilos[N];
and set nlast whenever you assign a new element in kilos. This way it is O(1).
for(int x=0;x<ctr-1;x++) //
{
if(employeenames[x].EmployeeNumber == log.Record)
{
EmployeeKilos[x].kilos[EmployeeKilos[x].nlast] = log.Kilometers;
EmployeeKilos[x].nlast++;
}
}

Resources