I frequently make use of jagged arrays in my programming. Often, they'll be static in size, but I'll be re-filling them with new data. In the past, I've just made use of the 'new' operator to wipe out the array, and then just re-initialise it. However, I suspect that it's probably not best practice.
Any advice on the best method to clear a jagged array out and zero all its values?
I'm familiar with Array.Clear, but as far as I'm aware, because Jagged arrays aren't technically contiguous, I believe I have to loop and clear each child individually?
Thanks in advance!
Jaspar
I would use Array.Clear()
int[][] jagged = new int[][] {
new int[] { 1, 2, 3, 4 },
new int[] { 11, 12 },
new int[] { 21, 22, 23 }
};
for (int i = 0; i < jagged.Length; i++)
{
Array.Clear(jagged[i], 0, jagged[i].Length);
}
instead of
for (int i = 0; i < jagged.Length; i++)
{
for (int j = 0; j < jagged[i].Length; j++)
{
jagged[i][j] = 0;
}
}
Yes, I believe that you will have to loop on the sub array.
A jagged array is an array of array. The default( refenence type ) is a null reference. So a Clear jagged array will be here an array of null references.
But you want each member of those array to be cleared so :
foreach (int[] subArray in jaggedArr)
{
Array.Clear (subArray, 0, subArray.Length);
}
It is enough to remove all existing references by assigning null to make array ready for Garbage Collection. (array=null)
Then it is possible to force garbage collection by calling (array.Collect()),
Related
I am trying to performance tune a routine that needs to sort 8 large arrays "in tandem", where one of the arrays is the array to sort by.
I've already taken care of sorting the first array using a method of my choosing (I'm using TimSort)
I've already taken care of making sure my array of sorted objects have a property denoting their original index. (e.g. sortedArray[0].OriginalIndex would return 2983 if previously unsortedArry[2983] turned out to be the first item)
This means if I were to loop over my now sorted array of objects, I think I can just get all other arrays sorted in the same order in the following naïve way:
private List<object[]> SortInTandem(IndexedObj[] sortedArray, List<object[]> arraysToSort)
for(int i = 0; i < sortedArray.length; i++) {
int originalIndex = sortedArray[i].OriginalIndex;
// Swap the corresponding index from all other arrays to their new position
foreach(object[] array in arraysToSort) {
object temp = array[i];
array[i] = array[originalIndex];
array[originalIndex] = temp;
}
}
return arraysToSort; // Returning original arrays sorted in-place
}
I believe the above algorithm to have the desired result, but it feels less efficient than it could be. (3 times as many assignments as needed?)
I also considered the following approach which minimizes assignments, but requires allocating new arrays to store sorted items, and garbage collecting the old arrays (unless I come up with a way to recycle the allocations between calls):
private List<object[]> SortInTandem(IndexedObj[] sortedArray, List<object[]> arraysToSort) =>
arraysToSort.Select(array =>
{
object[] tandemArray = new object[array.length];
for(int i = 0; i < sortedArray.length; i++)
tandemArray[i] = array[sortedArray[i].OriginalIndex];
}); // Returning newly-allocated arrays
This sort of thing is done continuously in a performance-critical area of code, so I'm looking for thoughts on how I might get the best of both worlds.
Thinking more about the second solution above (allocating new arrays) - it occurred to me that the list of arrays passed in can also be "repurposed" once their sorted variant has been produced, so I actually only need to allocate one new array and then I can reuse the ones passed in to prepare additional results:
// Note the allocated arraysToSort passed in will be repurposed to produced a new set of sorted
// arrays, so the caller must be sure to discard their references and only use what is returned.
private List<object[]> SortInTandem(IndexedObj[] sortedArray, List<object[]> arraysToSort)
{
List<object[]> sortedArrays = new List<object[]>(arraysToSort.Count);
object[] tandemArray = new object[array.length];
for(int i = 0; i < arraysToSort.Count; i++)
{
for(int j = 0; j < sortedArray.length; j++)
tandemArray[j] = array[sortedArray[j].OriginalIndex];
sortedArrays.Add(tandemArray);
tandemArray = arraysToSort[i];
}
return sortedArrays; // Returning one newly-allocated + all but one original arrays repurposed
}
I am trying to solve a challenge on a coding site. The problem is about int matrixes. I am using c# language.I need to create a function that takes a parameter as int[][] (integer matrix) and also return int[][] (another integer matrix). Starting of problem (the empty function given to me) is like that
int[][] boxBlur(int[][] image) {
}
and this is what i tried so far
int[][] boxBlur(int[][] image) {
int pixelLength = image[0].Length - 2;
int[][] newBox = new int[pixelLength][pixelLength];
int pixelSum = 0;
int c = 0;
for(int t = 0; t<pixelLength; t++)
{
for(int i = 0; i<pixelLength; i++)
{
for(int j = t; j < 3 + t ; j++)
{
for(int k = i; k < i+3 ; k++)
{
pixelSum += image[j][k];
}
}
newBox[t][i] = pixelSum / 9;
}
}
return newBox;
}
Now i don't have any problem with algorithm, probably it will work but the problem is that i can't define an Array like int[][]. It gives an error like Cannot implicitly convert type int to int[][] and when i try to create this array like
int[,] newBox = new int[pixelLength,pixelLength];
it also gives error because it says the return type is wrong and i can't change the return type so i need to define a matrix exactly like int[][].
Is there any way to do it or do i need to try another way?
int[][] is a jagged array, or in other words, an array of arrays.
When you see a int[], you understand it as an array of integers. That is, every "slot" of the array holds and integer. An array of arrays is exactly the same, except that every slot holds an array.
Once you understand that, it should make perfect sense why the correct way to initialize your jagged array is:
int[][] newBox = new int[pixelLength][];
Now you've said that newBox is an array of int arrays: newBox[0] is of type int[], newBox[1] is of type int[], etc. Because the default value of an array, like any other reference type, is null, the value of newBox[0], newBox[1], etc. is null; you need to initialize each and every one of them.
The advantage of jagged arrays is, of course, that each int[] can be the size you wish, hence the name jagged array.
So what you are essentially missing, once you initialize your jagged array correctly, is initalizing each and everyone of the int[] arrays before using them. You can do this inside the adequate loop.
Carrying on from here should be easy.
An interesting test to verify if you've understood everything correctly is initalizing and correctly filling up all the values of the following type:
int[][][] myHeadHurtsArray;
int[][] and int[,] are two different things. The first is Jagged Array, the second is Multidimensional Array.
When initializing jagged array you can give only the array length, not the length of all the arrays in it:
int[][] newBox = new int[pixelLength][];
And insert new array each time:
newBox[index] = new int[size];
For example: an array of varying-length arrays of integers.
In C++, we are used to doing things like:
int * * TwoDimAry = new int * [n] ;
for ( int i ( 0 ) ; i < n ; i ++ )
{
TwoDimAry[i] = new int [i + n] ;
}
In this case, if n == 3 then the result would be an array of three pointers to arrays of integers, and would appear like this:
http://img263.imageshack.us/img263/4149/multidimarray.png
Of course, .NET arrays are managed collections, so you don't have to deal with the manual allocation/deletion.
But declaring:
int[][] TwoDimAry ;
... in C# does not appear to have the same effect - namely, you have to innitialize ALL of the sub-arrays at the same time, and they have to be the same length.
I need my sub-arrays to be independent of each-other, as they are in native C++.
What's the best way to implement this using managed collections? Are there any drawbacks I should be aware of?
Like C++, you need to initialize every subarray in an int[][].
However, they don't need to have the same length. (That's why it's called a jagged array)
For example:
int[][] jagged1 = new int[][] { new int[1], new int[2], new int[3] };
Your C++ code can be translated directly to C#:
int[][] TwoDimAry = new int[n][];
for(int i = 0; i < n; i++) {
TwoDimAry[i] = new int[i + n];
}
Here is an example with a jagged array initialized with 1, 2, 3, .. elements for each row
int N = 20;
int[][] array = new int[N][]; // First index is rows, second is columns
for(int i=0; i < N; i++)
{
array[i] = new int[i+1]; // Initialize i-th row with 'i' columns
for( int j = 0; j <= i; j++)
{
array[i][j] = N*j+i; // Set a value for each column in the row
}
}
I have use this enough to know that there aren't many drawbacks overall. Hybrid appraches with List<int[]> or List<int>[] also work.
In .Net, most of the time you don't want to use arrays this way at all. This is because in .Net, arrays are thought of as a different animal from a collection. Managed, yes. Collection? Well, maybe, but it confuses terms because that means something special. If you want a collection (hint: most of the time you do), look in the Systems.Collections namespace, particularly Systems.Collections.Generic. It sounds like you really want either a List<List<int>> or a List<int[]>.
In my project I have a lot of code like this:
int[][] a = new int[firstDimension][];
for (int i=0; i<firstDimension; i++)
{
a[i] = new int[secondDimension];
}
Types of elements are different.
Is there any way of writing a method like
createArray(typeof(int), firstDimension, secondDimension);
and getting new int[firstDimension][secondDimension]?
Once again, type of elements is known only at runtime.
Generics should do the trick:
static T[][] CreateArray<T>(int rows, int cols)
{
T[][] array = new T[rows][];
for (int i = 0; i < array.GetLength(0); i++)
array[i] = new T[cols];
return array;
}
You do have to specify the type when calling this:
char[][] data = CreateArray<char>(10, 20);
Well you can do this:
int[,] array = new int[4,2];
What you get is called a multidimensional array (4x2). Here is a nice article about multidimensional arrays.
The term jagged array usually refers to arrays, that have different second dimensions. For example take:
int[][] jagged = new int[2][];
jagged[0] = new int[5]; // 5 elements
jagged[1] = new int[1]; // 1 element
so this is not a 2x5 array, but a jagged array..
If:
You definitely want a jagged array, and not a multi-dimensional one as mOsa mentions.
You definitely need it to be of dynamic type at runtime, and not at compile time using generics as Henk mentions.
You can use Array.CreateInstance something like:
static Array CreateArray (Type t, int rows, int cols)
{
Array arr = Array.CreateInstance (typeof(Array), rows);
for (int i = 0; i < rows; rows++) {
arr.SetValue (Array.CreateInstance(t, cols), i);
}
return arr;
}
But are you sure you need this to by dynamic type at runtime?
As mOsa mentioned, if you want rectangular jagged array, then you are better off using a multi-dimensional array.
int[,] array = new int[dimension, dimension2];
will generate a rectangular array.
The reason to use a jagged array, is if you want to create an array with different secondary dimensions. A jagged array is really an array of arrays, where as a multi-dimensional array is a slightly different beast.
I need to delete duplicate entries from an array, but can't use any new data structures and the same array should return only distinct elements. For example, if my array is 1,3,3,3,5,55,67,1 then the result should be 1,3,5,55,67.
I believe I have solved the problem, but I need your opinion on whether it is a good algorithm or if I need to change something.
public void DeleteDuplicate(int[] array)
{
int l = 0;
int newPosition = array.Length -1;
for (int i = 0; i < array.Length; i++)
{
for (int j = i + 1; j < array.Length-l; j++)
{
if (array[i] == array[j])
{
int temp = array[j];
array[j] = array[newPosition];
array[newPosition] = temp;
newPosition--;
l++;
}
}
}
Array.Resize(ref array, array.Length - l);
}
Your code is buggy. Try running it against {1, 1, 1} - I think it will return {1, 1}.
In general, the question whether you have to maintain the relative ordering of the elements. For example, whether it is possible to return {1, 2} for input {2, 1, 2, 1}.
If it is allowed, then the fastest solution will be:
sort input array
run once through it comparing a[i] with a[i+1] and removing duplicates in O(N)'
The total complexity would be O(N*logN), which is better than N^2 you proposed.
If you must preserve the initial ordering, then I am not ready to propose a solution.
Last time I checked C# allowed you to sort 2 arrays by using one for the comparisons and doing the swaps on both.
Here's what you can do:
Create an array indices that stores the numbers 0 to N-1.
Sort array and indices using array as the key.
Find the duplicates and set the indices of duplicates to N+1.
Sort array and indices using indices as key.
Resize the array to the correct size and presto.
This removes duplicates and preserves ordering.