C# Array.BinarySearch Problem - c#

Can anyone explain why this is happening?
ie. Even when 175 is present in the array at location 7, the array.binarysearch is returning a negative value?
Please see this image:
Code http://www.freeimagehosting.net/uploads/555fef4560.jpg

Did you sort your array beforehand? BinarySearch expects the array to be sorted. Otherwise, it may return incorrect results.
Also, you should check for >= 0, not > 0. The element can be present at index 0.

From the picture, the array is 220 elements and you only show the first 7. All 220 elements must be sorted, otherwise BinarySearch will fail.
If for instance you only use the first num elements, use BinarySearch(0, num, 175)

Make sure the array is sorted
Make sure the object you are searching for is of the same type as the objects int he array. It helps to use the generic version:
Array.BinarySearch(..)

You could use Type specific version to make sure your input parameters are correct if the array is sorted:
int[] array = new int[] { 1, 3, 4, 5, 175, 200, 300, 400 };
int index = Array.BinarySearch<int>(array, 175);
You'll get a compilation error if the input array or search parameter is not of type int.

Related

invert a specific part of a list C#

I need a program to reverse part of a list between two terminals.
Example :
List: 1, 2, 3, 3, 5, 4
Output: 1, 2, 3, 3, 4, 5 (Only the 4 and 5 are inverted)
I found this:
positionCrepe.Reverse(indexOfMaxToSearch, positionCrepe.Count);
But it doesn't work because I have a mistake:
System.ArgumentException: The offset and length were out of bounds for this table or the number is greater than the number of index elements at the end of the source collection.
However
indexOfMaxToSearch = 2
and
positionCrepe.count = 5
and so it does not exceed the index of the table
Anyone have a solution?
Thank you.
The second argument is how many elements you want to reverse, not how many elements there are in the list.
So if you want to reverse everything starting from indexOfMaxToSearch, you want to reverse positionCrepe.Count - indexOfMaxToSearch elements:
positionCrepe.Reverse(indexOfMaxToSearch, positionCrepe.Count - indexOfMaxToSearch);
The error message is actually saying that the first argument plus the second argument is out of range of the array.
if you look at the definition of Reverse,
index: The zero-based starting index of the range to reverse.
count: The number of elements in the range to reverse.
You can use the following to make it work. Count must be less then the remaining indecies
positionCrepe.Reverse(2, positionCrepe.Count - 2);

How to use a sizeof with an integer array to avoid "Array does not have a predefined size [...] is a variable and used like a type" [duplicate]

How can I determine size of an array (length / number of items) in C#?
If it's a one-dimensional array a,
a.Length
will give the number of elements of a.
If b is a rectangular multi-dimensional array (for example, int[,] b = new int[3, 5];)
b.Rank
will give the number of dimensions (2) and
b.GetLength(dimensionIndex)
will get the length of any given dimension (0-based indexing for the dimensions - so b.GetLength(0) is 3 and b.GetLength(1) is 5).
See System.Array documentation for more info.
As #Lucero points out in the comments, there is a concept of a "jagged array", which is really nothing more than a single-dimensional array of (typically single-dimensional) arrays.
For example, one could have the following:
int[][] c = new int[3][];
c[0] = new int[] {1, 2, 3};
c[1] = new int[] {3, 14};
c[2] = new int[] {1, 1, 2, 3, 5, 8, 13};
Note that the 3 members of c all have different lengths.
In this case, as before c.Length will indicate the number of elements of c, (3) and c[0].Length, c[1].Length, and c[2].Length will be 3, 2, and 7, respectively.
You can look at the documentation for Array to find out the answer to this question.
In this particular case you probably need Length:
int sizeOfArray = array.Length;
But since this is such a basic question and you no doubt have many more like this, rather than just telling you the answer I'd rather tell you how to find the answer yourself.
Visual Studio Intellisense
When you type the name of a variable and press the . key it shows you a list of all the methods, properties, events, etc. available on that object. When you highlight a member it gives you a brief description of what it does.
Press F1
If you find a method or property that might do what you want but you're not sure, you can move the cursor over it and press F1 to get help. Here you get a much more detailed description plus links to related information.
Search
The search terms size of array in C# gives many links that tells you the answer to your question and much more. One of the most important skills a programmer must learn is how to find information. It is often faster to find the answer yourself, especially if the same question has been asked before.
Use a tutorial
If you are just beginning to learn C# you will find it easier to follow a tutorial. I can recommend the C# tutorials on MSDN. If you want a book, I'd recommend Essential C#.
Stack Overflow
If you're not able to find the answer on your own, please feel free to post the question on Stack Overflow. But we appreciate it if you show that you have taken the effort to find the answer yourself first.
for 1 dimensional array
int[] listItems = new int[] {2,4,8};
int length = listItems.Length;
for multidimensional array
int length = listItems.Rank;
To get the size of 1 dimension
int length = listItems.GetLength(0);
yourArray.Length :)
With the Length property.
int[] foo = new int[10];
int n = foo.Length; // n == 10
For a single dimension array, you use the Length property:
int size = theArray.Length;
For multiple dimension arrays the Length property returns the total number of items in the array. You can use the GetLength method to get the size of one of the dimensions:
int size0 = theArray.GetLength(0);
In most of the general cases 'Length' and 'Count' are used.
Array:
int[] myArray = new int[size];
int noOfElements = myArray.Length;
Typed List Array:
List <int> myArray = new List<int>();
int noOfElements = myArray.Count;
it goes like this:
1D:
type[] name=new type[size] //or =new type[]{.....elements...}
2D:
type[][]name=new type[size][] //second brackets are emtpy
then as you use this array :
name[i]=new type[size_of_sec.Dim]
or You can declare something like a matrix
type[ , ] name=new type [size1,size2]
What has been missed so far is what I suddenly was irritated about:
How do I know the amount of items inside the array? Is .Length equal .Count of a List?
The answer is: the amount of items of type X which have been put into an array of type X created with new X[number] you have to carry yourself!
Eg. using a counter: int countItemsInArray = 0 and countItemsInArray++ for every assignment to your array.
(The array just created with new X[number] has all space for number items (references) of type X already allocated, you can assign to any place inside as your first assignment, for example (if number = 100 and the variable name = a) a[50] = new X();.
I don't know whether C# specifies the initial value of each place inside an array upon creation, if it doesn't or the initial value you cannot compare to (because it might be a value you yourself have put into the array), you would have to track which places inside the array you already assigned to too if you don't assign sequentially starting from 0 (in which case all places smaller than countItemsInArray would be assigned to).)
In your question size of an array (length / number of items) depending on whether / is meant to stand for "alternative" or "divide by" the latter still has to be covered (the "number of items" I just gave as "amount of items" and others gave .Length which corresponds to the value of number in my code above):
C# has a sizeof operator (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/sizeof). It's safe to use for built-in types (such as int) (and only operates on types (not variables)). Thus the size of an array b of type int in bytes would be b.Length * sizeof(int).
(Due to all space of an array already being allocated on creation, like mentioned above, and sizeof only working on types, no code like sizeof(variable)/sizeof(type) would work or yield the amount of items without tracking.)

Need to understand the behaviour of BinarySearch and IndexOf methods

I have List and its values is ("Brandenburg","Alabama" and "Alberta"). When i used BinarySearch("Brandenburg") method, it returns -4 instead of 0. but i can get the correct index, when sorted this list. Why it returns wrong value if I use the unsorted list?. And I have also get the correct index from IndexOf("Brandenburg") method. Which method is useful that i can use?.
Thanks in Advance,
Prithivi
It MUST be sorted, to use binary search. The reason you're getting -4 is;
Your collection isn't sorted and for binary search the list will 'cut' in half each iteration. So:
When it starts, the topIndex == 0 and bottom = 2
TopIndex -> (0) "Brandenburg",
(1) "Alabama"
BottomIndex -> (2) "Alberta
The binarysearch will check the item in the middle: (2-0) / 2 = 1. If you're searching for Brandenburg. It will compare Alabama with your search item. The letter B is 'bigger' than letter 'A'. So it moves the topIndex to index 1.
(0) "Brandenburg",
TopIndex -> (1) "Alabama"
BottomIndex -> (2) "Alberta
Then it will compare to the next 'middle' item. In this case again Alabama. (2-1) / 2 = 1. It will also be compare to the bottomIndex, but this is the last one.
When binarysearch returns a negative number, it means that the item cannot be found. The negative number is the Index where it should be inserten. (-result -1) So if you want the new item added, it should be inserted on index (--4 -1) == 3
Let me explain how binary search works.
Say you have this array:
{1, 3, 5, 7, 10, 15, 20}
And I want to find the index of 15. What binary search will do is that it looks at the middle of the array, 7. Is 7 greater or less than 15? If it is less than 15, do the same thing again on the second half of the array (10, 15, 20). If it is greater than 15, do it on the first half (1, 3, 5). If it is equal to 15, then that means 15 is found.
This means that the array must be sorted for binary search to work. This explains why doing a binary search on your array returns a negative number. Because obviously, the method can't find the string you requested using the binary search algorithm.
You can get the correct index with IndexOf. This is because IndexOf uses a linear search to find the item. It looks at each element in the array and compare to the one that you're finding. Therefore, whether the array is sorted doesn't matter.
Note: I have not read the source code of IndexOf. It might use a binary search if it finds that the array is sorted. This is only my guess.

Why does array-size declaration use "1" as the first index?

Something that I noticed about C#/Java is this seemingly (to me at the moment) inconsistent issue with array size declaration and the default first-index of array sizes.
When working with arrays, say you want to create a new integer array size 3, it would look like this:
int[] newArray = new int[3] {1, 2, 3};
Totally find and readable... Right?
The standard with programming languages seem to dictate that the "first" index is 0.
Using that logic, if I am interested in creating an array the size 3, I should really be writing this:
int[] newArray = new int[2] {1, 2, 3};
Wait a minute.. VS is throwing an error, saying an array initialize of length 2 is expected.
So there's an inconsistency with the first index in looping through an array and the array-size declaration? The former uses a 0-th based index, and the second a 1-th index.
It's not game-breaking/changing in any form or way, but I'm genuinely curious why there's a discrepancy here, or hell, if this is even an issue at all (like I say, it's not game-breaking in any way, but I'm curious as to why it's done this way).
I can at the moment think of reasons why 1-th based index would be used:
In a for-loop you would use < newArray.Length as opposed to < newArray.Length - 1 or < newArray.Length.
Working with Lists for awhile and then coming back to size-needs-to-be-declared-arrays caught me a bit off-guard.
Because you are declaring the array with the number of elements it will contain.
I am unsure how that is inconsistent.
How many times do you have to saw to cut a log in 3 pieces? Hint: not 3 times.
Also note how in your post title you incorrectly refer to the array size declaration as 'index'.
I think you are confusing the indexer with the length. You want to hold three elements (or variables) in your array, denoted by
...new int[3]...
and the elements in the curly brackets are the values, not the index. Index is still 0-based. Longform would look like this:
int[] newArray = new int[3];
newArray[0] = 1;
newArray[1] = 2;
newArray[2] = 3;
So in that, you can see where your zero-based index is as it relates to the values of your int[].
int[] newArray = new int[2] {1, 2, 3};
In English, this would translate you "I want a container that can hold 2 items but put 3 items in it". You are confusing the length of an array (how many items it can hold) with the index into the array which is 0-based in C-based languages (ex. C, C++, C#, Java, Javascript, Swift).
Also, consider what an array index really is (atleast with low level languages like C); it's an offset in memory from the base address of your array variable. So arr[n] translates to "take the address for arr, advance n * (the size of my type) bytes in memory, and give me the value at that calculated address. So when n = 0, you are referencing the value at the base memory address (the beginning of the array).
Answer provided by Wim Hollebrandse is absolutely great and correct, but wanted to expand on it a little bit to give OP a bit more understanding why indices start with 0 in most (but not all) languages.
As Wim stated, at declaration it is how many elements will be stored in an array, and that's quite palatable for human understanding. What confuses many is why 1st item is actually referred to as 0th (i.e. index 0)... The reason for this is the simple math that is needed to find seeked element in array.
All elements in array are stored sequentially in contiguous block. If the array is located for example at address 100 and hold integers (each integer of size 4 bytes), then when looking for the very first item, it would be located in the beginning of array, that is at address 100. The second item will be stored immediately after the first, or 100+4=104 address. 3rd item is stored after 2nd or at address 108.
So to calculate position of I-th element, if indices begin with 0, the math is simple:
I-th-address = address_of_array + I * sizeof(datatype)
e.g. for our example it is 100 + i * 4
if indices begin with 1, then math requires more operations:
Ith-address - address of array + (I-1) * sizeof(datatype)
... which is less efficient and unnecessary than the 0-based.
You are mixing the declaration of the array with the request of an array element. While declaring an array you specify the length of the array (number of elements), and this is 3, correct. When you request an element, the you specify the index, and the first index is 0. But you shouldn't mix the index and the length of the array.
In a for-loop, you should take < newArray.Length: If you have a length of 3, then the loop will start at 0 and go through index 0, 1 and 2. Then it stops, because 3 is not < 3.

Best way to remove duplicate value from an int array without using an extra array?

I need to remove duplicate value from an int array without using an extra array and after removing duplicate value from array how can i resize the length of array?
eg:-
int []arr = new int [] {1,2,1,3,3,5,6,1,3,2,8} //array length is 11
after removing duplicate value output should be as {1,2,3,5,6,8} // array length is 6
Is it possible then how??
**I am not allowed to use predefined methods, need to perform with proper logic only.
Fundamentally you can't: arrays are a fixed size within .NET. You can't resize them.
You could potentially keep a separate variable to indicate the "used" portion of the array, ending up with an array of (say) { 1, 2, 3, 5, 6, 8, 0, 0, 0, 0, 0 } and a "used length" of 6. It's not clear what aspect you're interested in when it comes to performance, other than avoiding using an extra array. For example, you could sort the array, then walk along and every time you come across consecutive equal elements, shuffle the remainder up one value.
As Jon has mentioned you can not resize array. The best approach is use a Hashset.
If you are not allowed to use Hashset, sort them. But here you are supposed to create a new array to hold result.

Categories

Resources