Convert a byte array to int array with padding - c#

I know I can convert a byte array to an int array with the following:
int[] bytesAsInts = yourBytes.Select(x => (int)x).ToArray();
How can I convert a byte array to an int array of a fixed size and pad the remaining with 0x00?
E.g., my byte array is 10 bytes, and I want to create an int array of length 14. The code should convert the 10 bytes of my byte array, and pad the remaining 4 with 0x00

Write yourself a reusable extension method that can pad a sequence:
static IEnumerable<T> AppendPadding(this IEnumerable<T> items, int totalCount, T paddingItem) {
int count = 0;
foreach (var item in items) {
yield return item;
count++;
}
for (int i = count; i < totalCount; i++)
yield return paddingItem;
}
And use it like this:
int[] bytesAsInts = yourBytes.Select(x => (int)x).AppendPadding(14, 0).ToArray();
This works on any kind of sequence with a single linear pass over the sequence. It is also lazy. Abstracting away the problem of padding a sequence allows you remove the complexity of doing the padding from the main algorithm. It is now hidden in some other place nobody has to care about. Factoring out unimportant details leads to clean code because all the complexity is hidden behind a well-defined interface.

int[] array = new int[14];
bytesAsInts.CopyTo(array, 4);

Maybe not most readable, but oneliner :)
int[] bytesAsInts = yourBytes.Select(x => (int)x)
.Concat(Enumerable.Repeat(0,14-yourBytes.Length)).ToArray();

#usr definitely has a great answer. Here's another way, not as robust. But explains the logic, useful for any language, implemented in its own way. Here desiredSize could be set by input.
int desiredSize = 14;
int[] myArray = new int[desiredSize ];
for(int i = 0; i < myArray.Length; i++)
{
if(i <= yourBytes.Length)
myArray[i] = (int)yourBytes[i];
else
myArray[i] = 0x00;
}

Related

How to append arrays in c#

I would like to get the output of this to be [1,2,3,4,...,200]. Any suggestions for how to go about this?
var Laser_data = 0;
var i = 0;
var j = 1;
int[] LaserData_200 = new int[200];
for (i = 0; i < LaserData_200.Length; i++)
{
Laser_data += j;
LaserData_200[i] = Laser_data;
Console.WriteLine(" " + LaserData_200[i]);
}
Current output:
1
2
3
4
ect.
Your array initialization and element assignment can be simplified massively. Your array is just the numbers 1 through 200 (inclusive). Enumerable.Range can generate that for you, then save it as an array.
int[] myArray = Enumerable.Range(1, 200).ToArray();
To print it all, string.Join it using a comma as a seperator.
Console.WriteLine($"[{string.Join(',', myArray)}]");
// [1,2,3,4,5,6,7,8,9,10,11,12,13, .... 200]
I see the title has nothing to do with the posted code.
So I am answering the question in the title.
Say you have two arrays a and b and you want to create a third array that combines the two arrays, then you write code like
int[] c = Enumerable.Concat(a, b).ToArray();
or you have and array a and you want to keep adding values to it in loop. When arrays are fixed size (a.IsFixedSize = true always) so you can do this efficiently.
The best solution is to use List<T> instead of an array
List<int> a = new List<int>()
for(int i=0; i<200; i++)
{
a.Add( i+1 );
}
and if you want an array in the end, you just do
int[] c= a.ToArray();

Selection sort time complexity for array type data structure in C#

I have implemented selection sort using an array (not array list) in C#. the time complexity mentioned at most places for selection sort is O(n^2).
In my implementation below, I see it as O(n^3). Is there a way to make it O(n^2)?
In many books, which define time complexity of selection sort as O(n^2), I see the author doesn't consider the time complexity for pop or element removal step in array which is also O(n).
using System;
public class SortArray
{
public int[] SlectionSort(int[] arr)
{
int[] newarr = new int[arr.Length];
for(int i=0; i<newarr.Length; i++)
{
int smallest_index = findSmallest(arr);
newarr[i] = arr[smallest_index];
arr = pop(arr, smallest_index);
}
return newarr;
}
public int findSmallest(int[] arr)
{
int smallest = arr[0];
int smallest_index = 0;
for(int i = 1; i < arr.Length; i++)
{
if(arr[i] < smallest)
{
smallest = arr[i];
smallest_index = i;
}
}
return smallest_index;
}
public static int[] pop(int[] arr, int index)
{
int size = arr.Length - 1;
int[] newArr = new int[size];
int n = 0;
for(int i=0; i < arr.Length; i++)
{
if( i > newArr.Length-1)
{
break;
}
if(i < index)
{
newArr[i] = arr[i];
}
else
{
newArr[i] = arr[i+1];
}
}
return newArr;
}
}
The short version is that you're delaying the selection sort by forcing it to operate on fixed (rather than dynamic) memory. When you see a general algorithm with a complexity listed, that's more of a guide than a promise. If you don't match the data structures to the algorithm, you're not going to be able to achieve the same upper-bound time complexity.
I see the author doesn't consider the time complexity for pop or element removal step in array which is also O(n).
Here's the sign that your input isn't organized right. For a more extreme example, if I insisted on storing my list on a tape, array access is O(n), because I'd need to wait for the tape to spool under the read-head. That doesn't mean that the algorithm is more complex; it means that the implementation is throwing roadblocks in the way of the algorithm.
In some cases that might be a necessary constraint. But for the case in the question, you just want a data structure that doesn't take an algorithm to remove and insert items, like a List.

dividing system.collections.bitarray into sub bitarrays of 32 bits each

I have searched in net but not getting exactly what I need.
I have a bitarray of size 15,936. I need to divide this bit array into list of bitarrays , with each bit array having 32 bits(15936/32 = 498 bitarray list).
Not able to find exactly how to divide bitarray. Please do help.
Thanks,
The first that you want 32-bit values makes this pretty easy, because you can copy it to an int[], then create one BitArray per int, passing the data by creating a single-element int array:
int[] values = new int[bigBitArray.Length / 32];
bigBitArray.CopyTo(values, 0);
var smallBitArrays = values.Select(v => new BitArray(new[] { v })).ToList();
Or more efficiently, reusing the same int[] for each iteration:
int[] values = new int[bigBitArray.Length / 32];
bigBitArray.CopyTo(values, 0);
// Reuse this on every iteration, to avoid creating more arrays than we need.
// Somewhat ugly, but more efficient.
int[] buffer = new int[1];
var smallBitArrays = values.Select(v =>
{
buffer[0] = v;
return new BitArray(buffer))
}).ToList();
If those give you the bit arrays in the opposite order to what you expect, just call Array.Reverse(values) after the CopyTo call.
It's a pity that BitArray doesn't have a constructor taking an existing array, offset and count... that would make it significantly more efficient. (As would a "slice copy" operation, of course.)
A more general purpose option would be to create an extension method precisely for that "slice copy" part:
public static BitArray CopySlice(this BitArray source, int offset, int length)
{
// Urgh: no CopyTo which only copies part of the BitArray
BitArray ret = new BitArray(length);
for (int i = 0; i < length; i++)
{
ret[i] = source[offset + i];
}
return ret;
}
Then:
var smallBitArrays = Enumerable
.Range(0, bigBitArray.Length / 32)
.Select(offset => bigBitArray.CopySlice(offset * 32, 32))
.ToList();
You can copy your bit array into an array of bytes, split that array into chunks and create new bit arrays:
const int subArraySizeBits = 32;
const int subArraySizeBytes = subArraySizeBits / 8;
byte[] bitData = new byte[myBitArray.Length / subArraySizeBytes];
myBitArray.CopyTo(bitData, 0);
List<BitArray> result = new List<BitArray>();
for (int index = 0; index < bitData.Length; index += subArraySizeBytes) {
byte[] subData = new byte[subArraySizeBytes];
Array.Copy(bitData, index * subArraySizeBytes, subData, 0, subArraySizeBytes);
result.Add(new BitArray(subData));
}

What is the fastest way to find Nth biggest number of an INT array?

I want a faster function to find the Nth biggest number of an Int array in C#. This function takes N and Array and returns index of that number.
Here is what i have already. It simply sorts the array and then returns the index of that number. It works perfectly but I'm not sure if this is the fastest way. it seems logical to be an algorithm without complete sorting.
static int myFunction(int[] array, int N){
int[] indexes = new int[array.Length];
for (int i = 0; i < indexes.Length; i++)
indexes[i] = i;
for (int i = 0; i < array.Length; i++)
{
for (int j = i + 1; j < array.Length; j++)
{
if (array[i] < array[j])
{
int m = array[j];
array[j] = array[i];
array[i] = m;
m = indexes[j];
indexes[j] = indexes[i];
indexes[i] = m;
}
}
}
return indexes[N];
}
some results :
myFunction(new int[] { 1, 3, 2, 0, 10 }, 0); //returns 4 (index of 10)
myFunction(new int[] { 1, 3, 2, 0, 10 }, 1); //returns 1 (index of 3)
myFunction(new int[] { 1, 3, 2, 0, 10 }, 2); //returns 2 (index of 2)
Randomized quickselect algorithm works in average case complexity O(n). Practically it's very rare to be O(n^2). It uses quicksort's partition function
If your array has a size of a zillion numbers and you need the fifth largest number then you are sorting a lot of numbers that you won't need.
Wouldn't it be faster to keep an ascending sorted sequence of length n (linked list?), and for every element check if it is larger than the first one (which is the smallest in the ascending order
If smaller: skip to the next element in your large array
If larger: remove the smallest one from your sorted array which is the first element and insert the larger element in the proper place, keep the array sorted.
After having scanned your complete array, the first element in your sorted sequence is the one you are looking for.
Most comparisons are only with the first element of your sorted array. You'll have to change the array N-times, one time for the N largest numbers. A change of the array is to remove the first element (the smallest) and find the place where to insert the new element to keep the array sorted
Correction: my statement that the array has to be changed N-time is incorrect. This can be seen most easily when offering an array sorted in ascending order: every compared number will be larger than the smallest in the N-size array, and thus cause a replace
This would be the implementation of #HaraldDutch's answer.
int get(int[] array, int n)
{
var comparer = Comparer<int>.Create((x, y) => array[x].CompareTo(array[y])); //compare the array entries, not the indices
var highestIndices = new SortedSet<int>(comparer);
for (var i = 0; i < array.Length; i++)
{
var entry = array[i];
if (highestIndices.Count < n) highestIndices.Add(i);
else if (array[highestIndices.Min] < entry)
{
highestIndices.Remove(highestIndices.Min);
highestIndices.Add(i);
}
}
return highestIndices.Min;
}
You'd have to pass in 1 instead of 0 though.
you need to use Selection algorithm
https://en.wikipedia.org/wiki/Selection_algorithm
here nice slides: https://c3p0demo.googlecode.com/svn/trunk/scalaDemo/script/Order_statistics.ppt
generally algorithm:
Select(A,n,i):
Divide input into ⌈n/5⌉ groups of size 5.
/* Partition on median-of-medians */
medians = array of each group’s median.
pivot = Select(medians, ⌈n/5⌉, ⌈n/10⌉)
Left Array L and Right Array G = partition(A, pivot)
/* Find ith element in L, pivot, or G */
k = |L| + 1
If i = k, return pivot
If i < k, return Select(L, k-1, i)
If i > k, return Select(G, n-k, i-k)
You could create a heap of size N which has the largest number as its first element (as opposed to the smallest one usually given). Then you walk through your integer array, and whenever you have an element smaller than the largest member of the heap, you insert it into the heap. If that makes the heap exceed a size of N, you remove the largest member in it.
That should be one of the cheapest ways to do this. Specific "nth largest of m" algorithms may beat it, but probably not asymptotically.
Your sorting algorithm is by far not the fastest. You should google for "Quicksort" for a much, much faster algorithm.
And after you have implemented Quicksort, you would then think about whether you really needed to sort the complete array. Say you want to find the 20 largest out of 10,000 numbers, why would you sort the remaining 9,980 numbers? You can easily modify Quicksort so that it will find the N largest numbers but mostly ignore the rest.
Maybe this could help someone. finding the nth largest number in an int array.
int[] arr = new int[] { 3, 2, 1, 5 };
Array.Sort(arr);
int elemCount = 0;
int? thirdLargestNumber = null;
foreach (var elem in arr)
{
var temp = arr.Skip(elemCount).ToArray();
if (temp.Length == 3) //replace `3` with variable.
{
thirdLargestNumber = temp[0];
break;
}
elemCount++;
}
Console.WriteLine($"Third largest number = {thirdLargestNumber}");

C# Dynamic multidimensional array

I have a function...
private double[,] AddToArray(double[,] array, double[] dataToAdd)
{
// Make a new row at the end of 'array' and copy values
// from 'dataToAdd' into the new row.
//
// Return the new, modified array.
}
However 'double[,]' isn't dynamic and I dont know what the final size of the array will be. I can create a List from it and add the new row to the list, but then I cant seem to convert it back to a double[,]. The List.ToArray() wants to output a jagged array (double[][]). This wont work. I'm interfacing with a program developed in LabVIEW and LV refuses to accept a jagged array. LV is happy with a fixed array ([,]).
Any help?
You could try this:
private double[,] AddToArray(double[,] array, double[] dataToAdd)
{
var dim0 = array.GetLength(0);
var dim1 = array.GetLength(1);
if (dim1 != dataToAdd.Length) throw new ArgumentException();
var na = new double[dim0 + 1, dim1];
Array.Copy(array, na, array.Length);
for (var i = 0; i < dim1; ++i) na[dim0, i] = dataToAdd[i];
return na;
}
It explicitly increments the high-order dimension by one, and also verifies that the length of the low-order dimension is equal to the dataToAdd array. I have not been able to any smarter copying from dataToAdd to the 2D array than by a for loop; it is not possible to apply Array.Copy for different ranked arrays.
You could always create the 2-dimensional array manually:
double[,] array = new double[list.Count, data.Length];
for(int i = 0;i < list.Count;++i)
for(int j = 0;j < data.Length;++j)
array[i, j] = list[i][j];
That is, of course, assuming that all of the 'dataToAdd' is of uniform length. Otherwise, what do you fill in the array for unused elements?

Categories

Resources