I want to write C code that takes a block of a 2D array and copies it into another 2D array by using the memcpy function. In the particular code I have included, I have tried to copy the last 3 columns of the 2x4 array matrix into the 2x3 array mat_copy.
double matrix[2][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}};
double mat_copy[2][3];
double sz = sizeof(mat_copy)/2;
for (int i = 0; i < 2; i++) {
memcpy(&mat_copy[i][1], &matrix[i][1], sz);
}
I'm getting the output: [0, 1, 2; 3, 5, 6] instead of [1, 2, 3; 5, 6, 7]. How does the memcpy function choose which addresses to copy once you give the initial pointer in memory? I know my error has to do with addressing the 2D arrays, but I don't know how to change it.
You're starting from 1 in your destination instead of 0, so you're copying past the end of the row.
Change
memcpy(&mat_copy[i][1], &matrix[i][1], sz);
to
memcpy(&mat_copy[i][0], &matrix[i][1], sz);
To copy the last 3 columns, you must pass the offset of columns 0 as destination. You can further simplify the code this way:
double matrix[2][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}};
double mat_copy[2][3];
for (int i = 0; i < 2; i++) {
memcpy(mat_copy[i], &matrix[i][1], sizeof(mat_copy[i]));
}
Related
I am stuck in this question for long time.
the question is - to move duplicates to the end of the array while preserving the order(time complexity must be O(nlogn)).
limitation:
order must be preserved.
can use only 1 helper array
the range of values in the array are not known and can be really large from n(which is the size fo the array).
values are positives.
time complexity - nlogn
example:
arr = {7, 3, 1, 2, 7, 9, 3, 2, 5, 9, 6, 2}, n = 12
result:
arr = {7, 3, 1, 2, 9, 5, 6, 2, 9, 2, 3, 7}
this what i did right now but i am stuck from thier:
copied original array to temp array
sort the temp array using quick sort
move duplicate to the end in temp array
i know that i need to do some comparison with the original array but this the part that i am stuck.
code:
int findDulpilcatesV2(int* arr, int n) {
int i, * tempArr, j = 0, countNonRepeatEl = 0, searchKeyIndex, elIndex;
tempArr = (int*)calloc(n, sizeof(int));
assert(tempArr);
// Saving original array in temp array
for (i = 0; i < n; i++)
{
tempArr[i] = arr[i];
}
// Sorting temp array
quickSort(tempArr, 0, n - 1);
// Move duplicates to the end
for (i = 0; i < n; i++)
{
if (tempArr[i] != tempArr[i+1])
{
swap(&tempArr[j], &tempArr[i]);
countNonRepeatEl++;
j++;
}
}
free(tempArr);
tempArr = NULL;
return countNonRepeatEl;
}
Provided that we have an integer array of arbitrary depth, how would we traverse through it in order to build a string that represents the array as a C-style initialization?
For instance:
int arr3D[2][3][2] = { {{0, 1}, {2, 3}, {4, 5}}, {{6, 7}, {8, 9}, {10, 11}} };
We only know:
the total number of values (in this case 12)
the number of "dimensions" (in this case 3)
each of the dimension indexes (in this case 2,3,2)
the values 0,1,2,3,4,5,6,7,8,9,10,11
How can we make a string out of that, that looks like this:
"{{{0,1},{2,3},{4,5}},{{6,7},{8,9},{10,11}}}" ?
Evidently, this can be done with a nested nested loop, but that would only work with a definite set of dimensions (3). What if we have 10 dimensions? That made me think I can use recursion, but then it became confusing when and how to put { } characters. I am currently thinking about a single linear scan that intelligently inserts { and } characters in the string 0,1,2,3,4,5,6,7,8,9,10,11 but I feel like the real-world approach would be something like an indefinite n-tree branch traversing algorithm.
As you mentioned there are no need for the ndim nested for loops; what you could do is to use concepts like stride. Like then in how many count you change a dimension and then you can build you string.
Since you have not written any example code, I will write pseudo code to show how this could be done. In final case, dimensions should be input and stride calculated dynamically. Also, it is better to build a string and print it at the end, but for exposition, I'll output character by character using printf().
void print_mat(int* ptr, int ndims, int* dims){
int *stride = malloc(sizeof(int)* ndims); // TODO: null check
// create stride array same size of dims
stride[ndims -1] = dims[ndims - 1];
for(int j = ndims - 2 ; j >= 0; j--)
stride[j] = dims[j] * stride[j + 1];
// loop over all elements, stride[0] has the length
for(int idx = 0 ; idx < stride[0]; idx++){
// print open { for each start dimension
for(int i = 0; i < ndims; i++)
if (idx % stride[i] == 0){printf("{");}
printf("%d", ptr[idx]);
// print close } for each end dimension
for(int i = 0; i < ndims; i++)
if ((idx + 1) % stride[ndims - i - 1] == 0){printf("}");}
printf(", "); // comma after each element
}
printf("\b\b \n"); // clear extra , at end (may not support in all terminals)
free(stride);
}
int main()
{
int arr3D[2][3][2] = { {{0, 1}, {2, 3}, {4, 5}}, {{6, 7}, {8, 9}, {10, 11}} };
int dims[3] = {2, 3, 2};
print_mat(&arr3D[0][0][0], 3, dims);
// same as
// print_mat((int *) arr3D, 3, dims);
return 0;
}
This produces the desired output:
{{{0, 1}, {2, 3}, {4, 5}}, {{6, 7}, {8, 9}, {10, 11}}}
I have a 2d array and my goal is to print the total length of the 2d array. However I get an error with this code. In the for loop header, the compiler wont recognize the name "arrays" and suggests I make a local variable with that name.
I have already tried to calculate the 1d arrays.length before the for loop, but that didn't work either as the compiler still didn't recognize the name "arrays"
int[][] arrays = { {2, 5, 3, 8, 5},
{3, 5, 1, 7, 2},
{ 6, 2, 8, 1}};
}
int Length = 0;
for (int i= 0; i< arrays.length; i++) {
Length += arrays[i].length;
}
int[][] arrays = { {2, 5, 3, 8, 5},
{3, 5, 1, 7, 2},
{ 6, 2, 8, 1}};
int Length = 0;
for (int i= 0; i< arrays.length; i++) {
Length += arrays[i].length;
System.out.println(+Length);
}
Hi LoFitz the problem i see is that you placed the name of the array before the brackets.Instead of:
int[][] arrays
use
int arrays [][]
hope this helps.
arrays[I][j].length
use this It may help u bruh
I am doing an problem on Leetcode. The question is that given an array and a value, remove all instances of that value in place and return the new length.
Or you can read it here:
int removeElement(int* nums, int numsSize, int val) {
int *nums_copy;
int count = 0;
int actual_count = 0;
while (actual_count < numsSize) {
if (nums[actual_count] != val) {
nums_copy[count] = nums[actual_count];
count++;
nums_copy = realloc(nums_copy, sizeof(int)* count);
}
actual_count++;
}
nums = nums_copy;
return actual_count;
}
When I tried to test it with [1, 2, 2, 3], 2, the output is [1, 2, 2, 3] while the expected output is [1, 3].
Firstly, you don't need to realloc, the problem says to remove the value in place. Secondly, what you need to do is to simply walk through the array and shift it one position to the left when you encounter the searched value. And decrement the resulted count.
The problem does not need to memory allocation. All that is needed is to have the matching elements towards the end of the list. Here is an example.
array = 3, 2, 5, 2, 7, 2
len = 6
val = 2
We want to achieve something like
array = 3, 7, 5, 2, 2, 2
newlength = 3
SOLUTION One approach is the following
Repeat:
Start with two marker (either index or pointer) one pointing to the leftmost and one pointing to the rightmost element
3, 2, 5, 2, 7, 2
L R
Move the left marker to the right if it matches to 'val'. Do it until the matching stops or it reaches the right marker.
3, 2, 5, 2, 7, 2
L R
(Opposite for right marker.) Move the right marker to the left if it matches to 'val'. Do it until the matching stops or it reaches the left marker.
3, 2, 5, 2, 7, 2
L R
Swap the elements corresponding to the left and right markers.
3, 7, 5, 2, 2, 2
L R
Go to Repeat.
Apparently, you have not specified how much memory you want to allocate after int *nums_copy. Use malloc from stdlib to allocate variable amount of memory on heap, or alloca to allocate on stack, but bear this in mind.
Here this should work:
int removeElement(int* nums, int numsSize, int val) {
int countNums = 0;
int countCpy = 0;
while (countNums < numsSize) {
if (nums[countNums] != val) {
// Copy the number.
nums[countCpy] = nums[countNums];
++ countCpy;
}
++ countNums;
}
return countCpy;
}
As for why this output you got was [1, 2, 2, 3], I don't really understand. As you're trying to set nums_copy[0] before having allocated nums_copy, you should be getting a segfault. I suppose it's due to the platform you're coding on.
The given code uses std::vector, so why not use its build-in functions?
int removeElement(vector<int>& nums,int val){
vector<int> newNums();
for (int i=0; i<nums.size(); i++){
if (nums[i]!=val){
newNums.push_back(nums[i]);
}
}
return newNums.size();
}
int removeElement(int* nums, int numsSize, int val) {
int i, j;
for(i = 0, j = 0 ; i < numsSize ; i++){
if( nums[i] == val ) continue;
nums[ j ] = nums[ i ]; // blind copy
j++;
}
/*
nums = realloc( nums, j * sizeof( int ) );
*/
return j; //actual_count
}
I have the following (incomplete) function:
/* Populates char* name with the named location of the ith (flat) element
* of an array with ndim dimensions where the length of each dimension
* is already stored in the int* dim.
*
* name: a pointer to where the name should be populated
* n: the base name of the array
* dim: an int[] containing the length of each dimension
* ndim: length of the dim array
* i: name of the iteration variable being used
**/
void populateName(char *name, const char *n, int *dim, int ndim, const char *i) {
strcpy(name, n);
char *loc = (char*)(name + strlen(n));
char *curr;
for (int k = 0; k < ndim; k++) {
...
sprintf(loc, "[%s]", curr);
loc += strlen(loc);
}
}
What should go in the "..." in the for loop? For example, calling populateName() with:
int dim[2] = {3, 4};
char name[1024];
populateName(name, "x", dim, 2, "i");
should result in something like:
name = "x[i / 3][i % 4]"
or some other valid name for accessing the ith location in an array defined as:
int x[3][4];
Context: I'm writing a C program which generates C programs which filter large amounts of data based on user-defined data types and rules written in an IDL.
Edit: A python function which returns a tuple containing the location / coordinates in the array might get me going in the right direction. In particular the following array should have each element correspond with it's flat position in the array (using pylab here):
In [14]: x
Out[14]:
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]],
[[12, 13, 14],
[15, 16, 17]]])
In [15]: x.flat.copy()
Out[15]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
A good approach to solve a problem like this one is to try out a few examples. Consider the following picture that shows the memory layout for a 3D array x[2][3][5]:
How can we convert offset 14 to position x[0][2][4]? Well, first, we see that each x[i] holds 15 (3*5) blocks, so first of all we determine to which block does 14 belong to, by computing the integer division 14/15 = 0. So, offset 14 is somewhere inside x[0].
We can now apply the same method. x[i][j] holds 5 blocks, so offset 14 belongs to block number 14/5 = 2. In fact, the correct calculation is (14/5)%3, as we will see for offset 18. And finally, x[i][j][k] holds single blocks, so the last index is given by 14%5. Think of it like this: we are interpreting these blocks of memory as if they had different sizes at each step. First, we assume everything is divided in chunks of 15 elements. Then, we assume everything is divided in chunks of 5 elements.
You can play with this example and see that offset 18 maps to x[1][0][3] because 18/15 = 1; (18/5)%3 = 0, and 18%5 = 3.
It can be seen that the general case is that for dimension n, we interpret the memory layout as if it was organized in j blocks, where j is the product of every dimension greater than n, so we have to index position (i/j)%n.
Here's my implementation:
void populateName(char *name, const char *n, int *dim, int ndim, const char *i) {
strcpy(name, n);
char *loc = (char*)(name + strlen(n));
int j;
int *mul = malloc(sizeof(int)*ndim);
mul[ndim-1] = 1;
/* Compute cumulative multipliers array */
for (j = ndim-2; j >= 0; j--) {
mul[j] = mul[j+1] * dim[j+1];
}
for (j = 0; j < ndim; j++) {
loc += sprintf(loc, "[(%s/%d)%%%d]", i, mul[j], dim[j]);
}
free(mul);
}
As you can see, it uses a cumulative array of multipliers, where mul[i] holds the product of every dimension greater than i.
By the way, you don't need curr; since sprintf returns the number of characters printed, we just have to move loc that same amount. It gets a little more efficient than calling strlen repeatedly after sprintf.
I don't have much time to test this, but with the example I showed, I get this:
x[(i/15)%2][(i/5)%3][(i/1)%5]
Which looks correct. Here's an example program:
int main()
{
int dims[] = { 2, 3, 5, 7, 9 };
char name[1024];
populateName(name, "x", dims, 5, "i");
printf("%s\n", name);
return 0;
}
This prints:
x[(i/945)%2][(i/315)%3][(i/63)%5][(i/9)%7][(i/1)%9]
It gets trickier to read for arbitrary n dimensional arrays, but the principle is always the same.