Displaying the values of an n-dimension array as a string - arrays

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}}}

Related

move duplicates to the end of array in c while preserving order - nlogn

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;
}

For loop wont recognizwe the name of the 2d array

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

Copying part of 2D array into another 2D array in C

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]));
}

C: Different value every time program is run

I have a simple function in C to get whether an array is sorted, but I seem to be getting different values every time. Sometimes I get 3 tests passed and sometimes I get 2 tests passed and am unsure what the problem is.
int is_sorted(int a[], int n)
{
for(int i = 0; i < n; i++)
{
if(a[i] > a[i + 1])
{
return 0;
}
}
return 1;
}
int main()
{
int a[] = {2, 4, 9, 8, 12};
int b[] = {-5, -2, 0, 8, 11, 15};
int aa[] = {2, 18, 12, 9, 1, 2, 8, 11, 16, 3};
int c[] = {4, 6, 8, 10};
npassed = 0;
if(!is_sorted(a, 5))
{
npassed++;
}
if(is_sorted(b, 6))
{
npassed++;
}
if(!is_sorted(aa, 10))
{
npassed++;
}
if(is_sorted(c, 5))
{
npassed++;
}
printf("number passed is_sorted : %i\n", npassed);
}
your function accepts two arguments:
a: the array
n: the arrays size
to check if it is sorted you iterate over all elements and see if its next element is bigger than itself. To do that, you count with i from zero (the lowest possible index) to n-1 (the highest possible index).
But you always check if i is greater than i+1. And what happens if you reach the last possible index for i? Then i+1 is equal to n and therefore outside the array. And what's outside your array is random data.

Remove elements from a given array

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
}

Resources