C# Ensure no duplicates in byte array - c#

What is the easiest way to ensure there are no duplicates and a byte array is in order, say from a network connection?

If you're on .NET 3.5, it's pretty easy to get unique items ...
var ba = new byte[6];
ba[0] = 1;
ba[1] = 1;
ba[2] = 2;
ba[2] = 2;
ba[3] = 3;
ba[4] = 4;
ba[5] = 4;
var res = ba.Distinct().ToArray(); // unique
Can you explain what you mean by "in order"?

create an array of 256 booleans and iterate over the byte array one by one.
set each value in the array to true when you encounter it. if you encounter an already true value then the byte array is in an invalid format
I don't quite follow what you mean by the "byte array is in order" bit
You could also use a bitarray
example:
bool CheckForDuplicates(byte[] arr)
{
bool[] map = new bool[256];
foreach (byte b in arr)
{
if (map[b] == true)
return false;
map[b] = true;
}
return true;
}

if you don't what to throw an exception or such if the same value is encountered twice you could do:
var set = new HashSet<byte>(byteArray);
if you by being in order mean sorted you can call the LINQ extension method Sort on the object set from above

Related

Finding how many elements are in a string array

I'm trying to find how many elements are in my string array, so I can add to that array from the first empty element.
Here's what I've tried to do:
int arrayLength = 0;
string[] fullName = new string[50];
if (fullName.Length > 0)
{
arrayLength = fullName.Length - 1;
}
and then from that refer to the first available empty element as:
fullName[arrayLength] = "Test";
I can also use this to see if the array is full or not, but my problem is arrayLength is always equal to 49, so my code seems to be counting the size of the entire array, not the size of the elements that are not empty.
Cheers!
you can use this function to calculate the length of your array.
private int countArray(string[] arr)
{
int res = arr.Length;
foreach (string item in arr)
{
if (String.IsNullOrEmpty(item))
{
res -= 1;
}
}
return res;
}
EDIT : To find the first empty element
private int firstEmpty(string[] arr)
{
int res = 0;
foreach (string item in arr)
{
if (String.IsNullOrEmpty(item))
{
return res;
}
res++;
}
return -1; // Array is full
}
I'm trying to find how many elements are in my string array,
array.Length
so I can add to that array from the first empty element.
Array's don't have empty elements; there's always something in there, though it could be null.
You could find that by scanning through until you hit a null, or by keeping track each time you add a new element.
If you're going to add new elements then, use List<string> this has an Add() method that will do what you want for you, as well as resizing when needed and so on.
You can likely then just use the list for the next part of the task, but if you really need an array it has a ToArray() method which will give you one.
So if you want to use the array instead of a list you still simply can get the number of empty elements like this:
int numberOfEmptyElements = fullName.Count(x => String.IsNullOrEmpty(x));
Try the below code
string[] fullName = new string[50];
fullName[0] = "Rihana";
fullName[1] = "Ronaldo";
int result = fullName.Count(i => i != null);
in result you will have the number of occupied positions. In this case 2, cause 2 arrays are filled. From there you can count the empty. :)

This seems like a bug in studio or compilator

Problem is that after Randomize func, array forcombo equals random_for_combo, but I do not equate them anywhere. Please help.
private void button1_Click(object sender, EventArgs e)
{
string sub = "1#2#3#4#5#6#7#8#9#10";
string[] split = sub.Split('#');
string[] forcombo = new string[split.Length / 2];
int s = 0;
for (int j = 1; j <= split.Length - 1; j += 2)
{
forcombo[s] = split[j];
s++;
}
string[] random_for_combo = new string[forcombo.Length];
random_for_combo = forcombo;
MessageBox.Show(forcombo[0] + forcombo[1] + forcombo[2] + forcombo[3] + forcombo[4], "Before random");
random_for_combo = RandomizeStrings(random_for_combo);
MessageBox.Show(forcombo[0]+forcombo[1]+forcombo[2]+forcombo[3]+forcombo[4], "After random");
}
public static string[] RandomizeStrings(string[] arr)
{
ArrayList l1 = new ArrayList(arr.Length);
ArrayList l2 = new ArrayList(arr.Length);
foreach (object k in arr)
{
l1.Add(k.ToString());
}
while (l1.Count > 0)
{
Random rnd = new Random();
int rand = rnd.Next(l1.Count);
l2.Add(l1[rand]);
l1.RemoveAt(rand);
Thread.Sleep(rnd.Next(50));
}
for (int i = 0; i < l2.Count; i++)
{
arr[i] = l2[i].ToString();
}
return arr;
}
Some helpless info to complete question..
There's a couple of problems with this code:
You're copying the reference from one array variable into another:
random_for_combo = forcombo;
This does not make the two variables contain two arrays that contain the same values, the two values now refer to the same one array in memory. Change one, and it will appear the other one changed as well. Think of the two variables as postit notes with the address of a house on them, the same address. If you go to the house and rearrange the furniture, "both houses" will appear to be changed. There is only one house however.
When you pass the array to the randomize method, you're passing a reference to the array, not a copy of the array, which means that if you change the contents of the array, you're not working on a copy, you're working on the original. This means that the array you get passed, and the array you return, is the same one array in memory
Probably not the source of the bugs in your question, but you shouldn't construct new Random objects every time you use it in a loop, instead construct it once and reuse, otherwise you risk getting back just a few distinct values.
Lastly, if your gut reaction is "this is a bug in visual studio or C#", then it almost never is, always work on the presumption that it is your own code that is faulty. By "almost never" I would say that the chance of you hitting a bug in C# or Visual Studio by chance is none.
To make a new array with the same contents of another, you have a few options:
Explicitly make an array and copy over the elements one by one:
random_for_combo = new string[forcombo.Length];
for (int i = 0; i < forcombo.Length; i++)
random_for_combo[i] = forcombo[i];
Use Array.Copy instead of the for-loop:
random_for_combo = new string[forcombo.Length];
Array.Copy(forcombo, random_for_combo, forcombo.Length);
Use the new Linq ToArray extension method:
random_for_combo = forcombo.ToArray();
Note that even though this looks like a no-op (since forcombo is an array), you'll actually get a new array with the same contents.
but you did here :
random_for_combo = forcombo;
you set random_for_combo so it point to forcombo.
if you want to use the original array than you need to copy it to new array
something like this (instead of the above line)
string[] random_for_combo = new string[forcombo.Length];
for (int i = 0; i < forcombo.Length; i++)
{
random_for_combo[i] = forcombo[i];
}

How do I check for duplicate answers in this array? c#

Sorry for the newbie question. Could someone help me out? Simple array here. What's the best/easiest method to check all the user input is unique and not duplicated? Thanks
private void btnNext_Click(object sender, EventArgs e)
{
string[] Numbers = new string[5];
Numbers[0] = txtNumber1.Text;
Numbers[1] = txtNumber2.Text;
Numbers[2] = txtNumber3.Text;
Numbers[3] = txtNumber4.Text;
Numbers[4] = txtNumber5.Text;
foreach (string Result in Numbers)
{
lbNumbers.Items.Add(Result);
}
txtNumber1.Clear();
txtNumber2.Clear();
txtNumber3.Clear();
txtNumber4.Clear();
txtNumber5.Clear();
}
}
}
I should have added I need to check to happen before the numbers are output. Thanks
One simple approach is via LINQ:
bool allUnique = Numbers.Distinct().Count() == Numbers.Length;
Another approach is using a HashSet<string>:
var set = new HashSet<string>(Numbers);
if (set.Count == Numbers.Count)
{
// all unique
}
or with Enumerable.All:
var set = new HashSet<string>();
// HashSet.Add returns a bool if the item was added because it was unique
bool allUnique = Numbers.All(text=> set.Add(text));
Enunmerable.All is more efficient when the sequence is very large since it does not create the set completely but one after each other and will return false as soon as it detects a duplicate.
Here's a demo of this effect: http://ideone.com/G48CYv
HashSet constructor memory consumption: 50 MB, duration: 00:00:00.2962615
Enumerable.All memory consumption: 0 MB, duration: 00:00:00.0004254
msdn
The HashSet<T> class provides high-performance set operations.
A set is a collection that contains no duplicate elements, and whose
elements are in no particular order.
The easiest way, in my opinion, would be to insert all values inside a set and then check if its size is equal to the array's size. A set can't contain duplicate values, so if any value is duplicate, it won't be inserted into the set.
This is also OK in complexity if you don't have millions of values, because insertion in a set is done in O(logn) time, so total check time will be O(nlogn).
If you want something optimal in complexity, you can do this in O(n) time by going through the array, and putting each value found into a hash map while incrementing its value: if value doesn't exist in set, you add it with count = 1. If it does exist, you increment its count.
Then, you go through the hash map and check that all values have a count of one.
If you are just trying to make sure that your listbox doesn't have dups then use this:
if(!lbNumbers.Items.Contains(Result))
lbNumbers.Items.Add(Result);
What about this:
public bool arrayContainsDuplicates(string[] array) {
for (int i = 0; i < array.Length - 2; i++) {
for (int j = i + 1; j < array.Length - 1; j++) {
if (array[i] == array[j]) return true;
}
}
return false;
}

How to delete a chosen element in array?

I have this assignment where I must delete a chosen element from an array, so I came up with this code:
strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
if (strItems[i] == strInput)
{
strItems[i] = null;
for (int x = 0; x < intAmount-i; x++)
{
i = i + 1;
strItems[i - 1] = strItems[i];
}
intAmount = intAmount - 1;
}
}
The problem is that, suppose I have an array [1,2,3,4,5,], and I want to delete 1. The output would be [2,3,4,5,5]. This also happens when I choose 2, but it does not happen when I choose any other number.
What am I doing wrong?
I'm assuming you are working with a basic array of strings:
var strItems = new string[] { "1", "2", "3", "4", "5" };
In .NET, that array is always going to be 5 elements long. In order to remove an element, you are going to have to copy the remaining elements to a new array and return it. Setting the value at a position to null does not remove it from the array.
Now, with things like LINQ this is very easy (not shown here), or you could cheat using the List<> collection and do this:
var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();
But I don't think that's going to teach you anything.
The first step is to find the index of the element you wish to remove. You can use Array.IndexOf to help you out. Let's find the middle element, "3":
int removeIndex = Array.IndexOf(strItems, "3");
If the element was not found, it will return a -1, so check for that before doing anything.
if (removeIndex >= 0)
{
// continue...
}
Finally you have to copy the elements (except the one at the index we don't want) to a new array. So, altogether, you end up with something like this (commented for explanation):
string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };
int removeIndex = Array.IndexOf(strItems, strInput);
if (removeIndex >= 0)
{
// declare and define a new array one element shorter than the old array
string[] newStrItems = new string[strItems.Length - 1];
// loop from 0 to the length of the new array, with i being the position
// in the new array, and j being the position in the old array
for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
{
// if the index equals the one we want to remove, bump
// j up by one to "skip" the value in the original array
if (i == removeIndex)
{
j++;
}
// assign the good element from the original array to the
// new array at the appropriate position
newStrItems[i] = strItems[j];
}
// overwrite the old array with the new one
strItems = newStrItems;
}
And now strItems will be the new array, minus the value specified for removal.
Arrays in C# are of a fixed size - once initialized you can only modify items, but you cannot add or remove items. If you want to delete an item from a collection you have two options:
1.) Create a new array that has all members of the original array minus the one you want to remove.
2.) Use a collection type that is resizable and allows to add or remove items like List<T> (List<int> in your case). This is what you would do in the "real world" if your collection is not static.
In your specific implementation i think u miss a break; statement, you should go out from the outer loop when you finish the inner loop. The assignment to null is not useful at all.
If the list is just a list of numbers why are you using strings? use integers directly if it is the case.
Your exercise seems to ask something like this, if you need to remove only one element.
public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
bool found = false;
for (int i = 0; i < array.Length; ++i)
{
if (found)
{
array[i - 1] = array[i];
}
else if (array[i] == value)
{
found = true;
}
}
return found;
}
This function will returns true if it find the specified falue, false if not.
It will move all items as you describe in your example, but of course, it will not change the size of the array.
Arrays are fixed size.
You cannot change the size of an array, simply, the language don't allows that.
Arrays are, were and will be always fixed size!
To remove an item from an array you should do something this:
public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
int count = array.Length - 1;
T[] result = new T[count];
if (index > 0)
Array.Copy(array, 0, result, 0, index - 1);
if (index < size)
Array.Copy(array, index + 1, result, index, size - index);
return result;
}
...
strItems = RemoveAt(strItems, index);
This function will create a new array that contains all elements except the one at the index you specify.
Now, why someone would do something like this instead of using a List or a Dictionary or wathever?
Use directly a List without using an array.
Can use Except method to filter the data
AllData = {10, 30, 20, 50}
FilterData = {30, 20}
Result = AllData.Except(​FilterData)
Result will be {10, 50}
Arrays are a fixed sized, you can't shorten their length without creating a new array. All you can do is store the length of valid elements in the array (ie. after you remove 1 the length is 4).
Also, I'm not sure if the order of elements in your array is important, but if it's not you could swap the first and last elements rather than moving every element after the one that's removed forward 1 position.
An alternative to using an array is using a collection such as an ArrayList which will take care of resizing, removing and keeping a count of the amount of items in it, plus a lot more.
However, since this is homework you might have to use arrays. Either keep track of the length with a variable, as opposed to using array.length, or create a new array each time you want to change the size. If you don't have to use arrays then look at the collections you can use in C#.

Initializing an integer array

string dosage = "2/3/5 mg";
string[] dosageStringArray = dosage.Split('/');
int[] dosageIntArray = null;
for (int i = 0; i <= dosageStringArray.Length; i++)
{
if (i == dosageStringArray.Length)
{
string[] lastDigit = dosageStringArray[i].Split(' ');
dosageIntArray[i] = Common.Utility.ConvertToInt(lastDigit[0]);
}
else
{
dosageIntArray[i] = Common.Utility.ConvertToInt(dosageStringArray[i]);
}
}
I am getting the exception on this line: dosageIntArray[i] = Common.Utility.ConvertToInt(dosageStringArray[i]);
I am unable to resolve this issue. Not getting where the problem is. But this line int[] dosageIntArray = null; is looking suspicious.
Exception: Object reference not set to an instance of an object.
The biggest problem with your solution is not the missing array declaration, but rather how
you'd parse the following code:
string dosage = "2/13/5 mg";
Since your problem is surely domain specific, this may not arise, but some variation of two digits representing same integer.
The following solution splits the string on forward slash, then removes any non-digits from the substrings before converting them to integers.
Regex digitsOnly = new Regex(#"[^\d]");
var array = dosage.Split('/')
.Select(num => int.Parse(digitsOnly.Replace(num, string.Empty)))
.ToArray();
Or whatever that looks like with the cuddly Linq synthax.
You are looking for something like
int[] dosageIntArray = new int[dosageStringArray.Length];
You are trying to access a null array (dosageIntArray) here:
dosageIntArray[i] = Common.Utility.ConvertToInt(lastDigit[0]);
You need to initialize it before you can access it like that.
You have to allocate dosageIntArray like this:
in[] dosageIntArray = new int[dosageStringArray.Length];
Also, you have another bug in your code:
Index of last element of an array is Length - 1.
Your for statement should read as:
for (int i = 0; i < dosageStringArray.Length; i++)
or
for (int i = 0; i <= (dosageStringArray.Length - 1); i++)
The former is preferred and is the most common style you will see.
I strongly recommend you use Lists instead of Arrays. You don't need to define the size of the List; just add items to it. It's very functional and much easier to use.
As alternative approach:
var dosage = "2/3/5 mg";
int[] dosageIntArray = Regex.Matches(dosage, #"\d+")
.Select(m => int.Parse(m.Value))
.ToArray();

Categories