This question already exists:
Closed 11 years ago.
Possible Duplicate:
Fastest way to get range complement
I have a sorted array of nonoverlaping ranges for example (0,2],(2,4],(6,9] and I wish to get it's complement with (0,12] which shoud return (4,6],(9,12] .Whats the fastest way to do that?
Assume your input data is an array of this form:
{ 0, 2, 2, 4, 6, 9 }
Simply add the new elements 0 and 12 to the beginning and end, and you have
{ 0, 0, 2, 2, 4, 6, 9, 12 }
And reinterpreting consecutive pairs as intervals, you have:
(0, 0]
(2, 2]
(4, 6]
(9, 12]
The fact that you have degenerate intervals makes this something of a mess, but if your original list did not have any degenerate intervals, your output list would not either.
Depending on the format of your data and whether you can do in-place modification, this operation may be O(1).
I think it takes O(n) assuming n as the size of the sorted array.
Because you should check the gap between every adjacent ranges.
P.S. I guess it is your homework!
create one list of 2*n numbers. {a[0] .. a[2n-1]} by merging all intervals. It's sorted by construction.
ignore the pairs (a[i], a[i+1]) where i is odd and a[i]==a[i+1].
put at the front the lowest possible value.
put at the back the highest possible value.
splice two by two, you obtain the complement.
Related
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);
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.
We are writing a C# application that will help to remove unnecessary data repeaters. A repeater can only be removed in the case that all data it receives are received by other repeaters. What we need as a first step is explained bellow:
I have collection of int arrays, for example
a. {1, 2, 3, 4, 5}
b. {2, 4, 6, 7}
c. {1, 3, 5, 8, 11, 100}
It may be thousands of such arrays. I need to find arrays that can be removed. An array can only be removed in the case that all its numbers are included in other arrays. In the example above, array a can be removed because its numbers 2 and 4 are in array b and numbers 1, 3, 5 are in array c.
What the best way to do such operation?
This is not optimized solution for minimal number of arrays left.
make the abundance dictionary for the member of arrays. for example:
1 => 2
2 => 2
3 => 2
4 => 2
5 => 2
6 => 1
7 => 1
...
Check each of arrays and if abundance of all members are greater than 1, remove array and reduce the count of each number in your dictionary.
Getting the minimum number of remaining arrays (as opposed to a subset of arrays where no more arrays can be removed) is the NP-hard set cover problem. Even with thousands of arrays, however, there's a good chance that, if you apply a mixed integer program solver to the formulation in the linked Wikipedia article, it will be able to find the optimal solution.
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.
I am using C# and have a list of int numbers which contains different numbers such as {34,36,40,35,37,38,39,4,5,3}. Now I need a script to find the different ranges in the list and write it on a file. for this example it would be: (34-40) and (3-5). What is the quick way to do it?
thanks for the help in advance;
The easiest way would be to sort the array and then do a single sequential pass to capture the ranges. That will most likely be fast enough for your purposes.
Two techniques come to mind: histogramming and sorting. Histogramming will be good for dense number sets (where you have most of the numbers between min and max) and sorting will be good if you have sparse number sets (very few of the numbers between min and max are actually used).
For histogramming, simply walk the array and set a Boolean flag to True in the corresponding position histogram, then walk the histogram looking for runs of True (default should be false).
For sorting, simply sort the array using the best applicable sorting technique, then walk the sorted array looking for contiguous runs.
EDIT: some examples.
Let's say you have an array with the first 1,000,000 positive integers, but all even multiples of 191 are removed (you don't know this ahead of time). Histogramming will be a better approach here.
Let's say you have an array containing powers of 2 (2, 4, 8, 16, ...) and 3 (3, 9, 27, 81, ...). For large lists, the list will be fairly sparse and sorting should be expected to do better.
As Mike said, first sort the list. Now, starting with the first element, remember that element, then compare it with the next one. If the next element is 1 greater than the current one, you have a contiguous series. Continue this until the next number is NOT contiguous. When you reach that point, you have a range from the first remembered value to the current value. Remember/output that range, then start again with the next value as the first element of a new series. This will execute in roughly 2N time (linear).
I would sort them and then check for consecutive numbers. If the difference > 1 you have a new range.