How to read a range of bytes from a bytearray in c# - c#

I have to read a range of bytes from a byte array. I have the starting position and the ending position to read.
-(NSData *) getSubDataFrom:(int)stPos To:(int)endPos withData:(NSData *) data{
NSRange range = NSMakeRange(stPos, endPos);
return [data subDataWithRage:range];
}
The above code in ObjectiveC reads the range of data(bytes) from a NSData(byteArray). Is there any equivelent method in c# to do the same. or how else we can do this. Please advise!

What do you mean by read? Copy a range of bytes into another byte array?
var mainArray = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
var startPos = 5;
var endPos = 10;
var subset = new byte[endPos - startPos + 1];
Array.Copy(mainArray, startPos, subset, 0, endPos - startPos + 1);
From MSDN

Try the Array.Copy() or Array.CopyTo() method.

Related

How do I copy the array elements and also reversing certain elements with Array.Copy() in c#?

Elements of SourceArray are being copied to 2 separate Arrays namely DestArray1 and DestArray2.
output:
DestArray1 will have the first 4 elements of SourceArray but in the reverse form [4 3 2 1]
DestArray2 will have the last 4 elements of SourceArray. [5 6 7 8]
I want to replace the for loop with Array.Copy() method
if not reversed then Array.Copy() works kind of fine except for the last element, but to copy with reverse, it seems the Array.Copy doesn't work or I am not able to implement it.
int i, j;
int bytelength =8;
int halfbytelength = 4;
byte[] SourceArray = new byte[]{ 1, 2, 3, 4, 5, 6, 7, 8 };
byte[] DestArray1 = new byte[4];
byte[] DestArray2 = new byte[4];
for (i = halfbytelength - 1, j = 0; i >= 0; i -= 1, j++)
{
DestArray1[j] = SourceArray[i];
}
for (i = halfbytelength; i < bytelength; i += 1)
{
DestArray2[i - halfbytelength] = SourceArray[i];
}
I tried following the code but the results are not as expected as seen in(Results:), is there a way to do it?
Array.Copy(SourceArray, 0, DestArray1, 3, 0);
Array.Copy(SourceArray, 4, DestArray2, 0, 3);
Result:
DestArray1: [0 0 0 0]
DestArray2: [5 6 7 0]
First array.
To reverse array you can just call Array.Reverse() after copying:
Array.Copy(SourceArray, 0, DestArray1, 0, 4);
Array.Reverse(DestArray1);
Second array.
if not reversed then Array.Copy() works kind of fine except for the
last element
Because you pass invalid count of elements to copy (last parameter):
Array.Copy(SourceArray, 4, DestArray2, 0, 3); // 3 - elements count, not an index
Simply replace 3 with 4:
Array.Copy(SourceArray, 4, DestArray2, 0, 4); // 4 and it will copy including the last element

Quick Sort working for small input - Need Fresh Pair of eye to find bug

I know there are lot of resources on QuickSort but I need a fresh pair of eyes to catch a bug. I have written the QuickSort Algorithm, but it works for small array, but with large array it throws invalid result (last 3-4 elements didn't sort at all).
Test Case 1:
Input: { 5, 7, 2, 8, 10, 15, 14, 16, 16, 19, 20, 19, 3, 1, 5 }
OutPut: 1,2,3,5,10,14,15,16,16,19,20,19,7,5,8 (WRONG)
Test Case 2:
Input: { 5,1,15,2,8}
Output: 1,2,5,8,15
[TestMethod]
public void QuickSort_test()
{
//input
int[] input = InputArray();
//Algo
int n = input.Length-1;
QuickSort(0,n,input);
//matching result
bool isSorted = IsSorted(input);
Assert.AreEqual(true, isSorted);
}
private void QuickSort(int low, int high, int[] arr)
{
if(low< high)
{
//finding pivot correct index
int idxPivot = Partition(low, high, arr);
//Recursive QuickSort, on elements left on pivot and elements right on pivot
int h = high - idxPivot;
QuickSort(low, idxPivot - 1, arr); //left of pivot
QuickSort(idxPivot + 1, h, arr); //right of pivot
}
}
private int Partition(int low, int high, int[] arr)
{
int pivot = arr[high];
int idxp = low - 1; //smaller than pivot
for (int i = low; i < high; i++) //since element at high is already pivot, no need to run loop till that
{
if(arr[i]< pivot) //current ele < pivot . increment pivotsmallerIndex and swap current element with pivot smaller index
// hence making current element as the smaller element from pivot
{
idxp++;
//swapping
int temp = arr[idxp];
arr[idxp] = arr[i];
arr[i] = temp;
}
}
//idxp contains the last smallest element from the pivot
//so swapping pivot with the next element of idxp
int temp1 = arr[idxp + 1];
arr[idxp+1] = pivot;
arr[high] = temp1;
//return index of pivot, since it is added at idxp+1 now
return idxp + 1;
}
public int[] InputArray()
{
return new int[] { 5, 7, 2, 8, 10, 15, 14, 16, 16, 19, 20, 19, 3, 1, 5 };
//return new int[] { 5,1,15,2,8};
}

Re sizing array [duplicate]

This question already has answers here:
Deleting A Specified Element In An Array Using Random Class
(4 answers)
Closed 9 years ago.
int oldLength = numbers.Length;
int[] arrTmp = numbers;
numbers = new int[oldLength - 1];
Array.Copy(arrTmp, numbers, Token);
Array.Copy(arrTmp, r+1, numbers, Token, oldLength - Token - 1);
This all i got to remove a specified element from a value type array but it doesn't work.
I got 4 elements of value type array. I have stored 4 different numbers in it.
array[0] = 2;
array[1] = 4;
array[2] = 6;
array[3] = 8;
i got a random class to randomly pick a number if it is 2 has to be removed from my array in an ascending sequential order each element should be inspected and eliminated.
You would do much easier using the List class
List<int> l = new List<int>();
l.Add(2);
l.Add(4);
...
l.Remove(2);
int oldLength = numbers.Length;
int[] arrTmp = new int[oldLength - 1];
for(int i = 0, j = 0; i < oldLength || j < arrTmp.Length; i++)
{
if(numbers[i] == Token)
continue;
arrTmp[j++] = numbers[i];
}
using linq:
var newArray = numbers.Where(n=> n!= Token).ToArray();
This would be the general approach:
int oldLength = numbers.Length;
int[] arrTmp = numbers;
numbers = new int[oldLength - 1];
Array.Copy(arrTmp, numbers, r);
Array.Copy(arrTmp, r + 1, numbers, r, oldLength - r - 1);
Note the use of r everywhere. Here r would be the index of the element to omit.
If you really need to use plain arrays and copy their contents using Array.Copy (which is not a common way of handling things in .NET), then start by using a pen and write down correct indices and lengths of the array parts you are trying to copy.
Starting to code the solution before you know how to solve it won't get you far.
So, start with an example array and a random index:
// starting array
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7 };
// index to remove
int indexToRemove = new Random().Next(array.Length);
Now, presume that indexToRemove is 3 and try to do it by hand:
Part 1: { 0, 1, 2 } (start = 0, length = 3)
Part 2: { 4, 5, 6, 7 } (start = 4, length = 4)
From this concrete example, you can try to infer the general formula for offset and length of these two array parts:
Part 1: start = 0, length = (indexToRemove - 1)
Part 2: start = (indexToRemove + 1), length = (array.Length - indexToRemove - 1)
The code itself is then trivial:
var len = array.Length;
var newArray = new int[len - 1];
Array.Copy(array, 0, newArray, 0, indexToRemove - 1);
Array.Copy(array, indexToRemove + 1, newArray, indexToRemove, len - indexToRemove - 1);
Additionally, the Array.Copy can be used to copy a part of an array over itself, which means you can just move the second part of the array back by one position, and then resize the initial array using Array.Resize:
// do not create a new array, but simply "move" the 2nd part to left
Array.Copy(array, indexToRemove + 1, array, indexToRemove, len - indexToRemove - 1);
// finally, resize the original array
Array.Resize(ref array, array.Length - 1);
Of course, if you simply used a List<int>, then you would simply use the List<T>.RemoveAt method to remove the item:
var list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int indexToRemove = new Random().Next(list.Count);
list.RemoveAt(indexToRemove);

C#, How to split a byte array by delimiter?

I have a byte array that contains a collection of 2 byte hexadecimal numbers separated by ','. How could it be split by ',' and then the numbers be converted to integers?
The byte array contains values in ascii format.
edit:
Example
My valid character range is 0 to 9 ,A to F and comma
so my stream should look like
70, 67, 65, 57, 44, 55, 68, 66, 53, 44....
this would be equivalent to hexadecimal
FCA9 and 7DB5
If your byte array is truly ASCII encoded (ONE byte per character), then the following would work:
int[] ints = Encoding.ASCII.GetString(asciiEncodedBytes).Split(',')
.Select(x => Convert.ToInt32(x,16)).ToArray();
This will handle mixed case and variable length hex numbers, too.
I would convert the byte array to string and then use String.Split(',')
This should work, though my C# is a bit rusty...
byte[] input = { 1, 0, 0, 0, ',', 10, 15, ',', 100, 0, 0, 0, ',' };
List<int> output = new List<int>();
int lastIndex = 0;
for (int i = 0; i < input.Length; i ++) {
if (input[i] == ',')
{
if (i - lastIndex == 4)
{
byte[] tmp = { input[i - 4], input[i - 3], input[i - 2], input[i - 1] };
output.Add(BitConverter.ToInt32(tmp, 0));
}
lastIndex = i + 1;
}
}

Finding the length of the common prefix in two bytes

Given two bytes, how would I find the length of the common bits at the start of the two bytes.
For example:
9 == 00001001
6 == 00000110
Common prefix is 0000, length 4
I'm working in C#, so please stick to C# operations only.
Addendum: This particular piece of code will run thousands of times and needs to be very fast.
byte x = 9;
byte y = 6;
while ( x != y )
{
x >>= 1;
y >>= 1;
}
Basically, remove a bit from the right of each number until the two are equal. When they become equal, their bits are equal too.
You can keep track of the length of the prefix easily by introducing another variable. I'll leave that to you.
If you want it to be fast, and considering that you're dealing with bytes, why not precompute the values and return the answer in a single operation? Run this algorithm for all possible combinations of two bytes and store the result in a table.
You only have 2^8 * 2^8 = 2^16 possibilities (2^15 actually, because x = 6 and y = 9 is the same as x = 9 and y = 6). If you can afford the initial time and memory, precomputation should be fastest in the end.
Edit:
You got a solution that's at least better for precomputation and probably faster in general: find the leftmost 1 bit in x ^ y. Using this, build a table Pre where Pre[i] = position of leftmost 1 bit in i. You only need 2^8 bytes for this table.
EDIT: Thanks to the comments, I found that I misunderstood the problem. (Below is a fixed version).
With a lookup table:
readonly static int[] bytePrefix = new int[] {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
And use it XORing the two bytes:
bytePrefix[9 ^ 6]
I believe this is as fast as it can get, it's just one XOR operation and an array lookup (you can also change it to 2 array lookups, but it would use 256 times more memory and probably be slower, bitwise it really fast).
First get the binary difference between the bytes using the xor operator. Then you just shift bits out to the right until the difference is zero:
byte b1 = 6;
byte b2 = 9;
int length = 8;
for (int diff = b1 ^ b2; diff != 0; length--) diff >>= 1;
This will give you a minimum of calculations in the loop, so it will be rather fast.
If you're in a space-limited environment (which obviously you're not if you're using C#, but just in general) and can't afford a lookup table:
byte test = byte1 ^ byte2;
int length = 0;
if ((test & 0x80) == 0)
{
if ((test & 0x40) == 0)
{
if ((test & 0x20) == 0)
{
if ((test & 0x10) == 0)
{
// I think you get the idea by now.
// Repeat for the lower nibble.
}
else
length = 3;
}
else
length = 2;
}
else
length = 1;
}
This is basically an unraveled loop to find the first 1 bit in the XOR'd number. I don't think it can get any faster than this without the lookup table.
This can be restated as a simpler problem with a known fast solution:
Find the left-most true bit in X ^ Y.
Some code (apparently code can't immediately follow a bulleted list?!?)
int findCommonPrefix(long x, long y, out long common)
{
int prefixPlace = 0;
int testPlace = 32;
long w, mismatch = x ^ y;
do {
w = mismatch >> testPlace;
if (w != 0) { prefixPlace |= testPlace; mismatch = w; }
testPlace >>= 1;
} while (testPlace != 0);
common = x >> prefixPlace;
return 64 - prefixPlace;
}
This needs only 6 iterations to find the common prefix in a 64-bit long, the byte version will need only 3 iterations. Unroll the loop for even more speed.
Another approach using exclusive or (xor):
public int GetCommonPrefixLength(byte a, byte b)
{
int c = a ^ b;
int len = -1;
while ((++len < 8) && ((c & 0x80) == 0))
c = c << 1;
return len;
}
Here's a procedural way:
int r = 8;
while (a != b)
{
a >>= 1;
b >>= 1;
r -= 1;
}
Here's a way that uses a lookup table with just 256 entries:
int[] lookupTable;
void createLookupTable()
{
lookupTable = new int[256];
for (int a = 0; a <= 255; ++a)
{
int n = 8;
byte b = (byte)a;
while (b > 0) {
b >>= 1;
n -= 1;
}
lookupTable[a] = n;
}
}
int commonPrefix(byte a, byte b)
{
return lookupTable[a ^ b];
}
And just for fun here's a way to do it with LINQ:
int r = 8 - Enumerable.Range(0, 9).Where(n => a >> n == b >> n).First();
Here's one without a table or a loop:
len = (a^b) ? (7 - (int)Math.Log( a^b, 2)) : 8;
Explanation:
log2 X is the power to which the number 2 must be raised to obtain the value X. Since each bit in a binary number represents the next power of 2, you can use this fact to find the highest bit set (counting from 0):
2**0 = 1 = 0b0001; log2(1) = 0
2**1 = 2 = 0b0010; log2(2) = 1
2**1.6 =~3 = 0b0011; log2(3) =~1.6; (int)log2(3) = 1
2**2 = 4 = 0b0100; log2(4) = 2
...
2**3 = 8 = 0b1000; log2(8) = 3
So the code works by taking a XOR b, which sets only the bits which are different. If the result is non-zero, we use log2 to find the highest bit set. 7 less the result gives the number of leading zeros = the number of common bits. There is a special case when a XOR b == 0: log2(0) is -Infinity, so that won't work, but we know that all the bits must match, so the answer is 8.
int i;
for (i=0;i<sizeof(byte);i++)
if (a >> sizeof(byte)-i != b >> sizeof(byte)-i) break;
The 256-byte table versions seem quite nice; depending upon caching and branching issues, a 16-byte table version might or might not run faster. Something like:
/* Assumes table[16] is defined similarly to the table[256] in earlier examples */
unsigned int find_mismatch(unsigned char a, unsigned char b)
{
unsigned char mismatch;
mismatch = a^b;
if (mismatch & 0xF0)
return table[mismatch >> 4];
else
return table[mismatch]+4;
}
More instructions, including a branch, but since the table is now only 16 bytes it would take only one or two cache misses to fill entirely. Another approach, using a total of three lookups on a 16-byte table and a five-byte table, but no branching:
unsigned char table2[5] = {0,0,0,0,0xFF};
unsigned int find_mismatch(unsigned char a, unsigned char b)
{
unsigned char mismatch,temp2;
mismatch = a^b;
temp2 = table[mismatch >> 4];
return temp2 + (table2[temp2] & table[mismatch & 15]);
}
One would have to do some profiling in the real application to see whether the reduced cache load of the smaller tables was sufficient to offset the extra instructions.

Categories

Resources