Obtaining the min and max of a two-dimensional array using LINQ - c#

How would you obtain the min and max of a two-dimensional array using LINQ? And to be clear, I mean the min/max of the all items in the array (not the min/max of a particular dimension).
Or am I just going to have to loop through the old fashioned way?

Since Array implements IEnumerable you can just do this:
var arr = new int[2, 2] {{1,2}, {3, 4}};
int max = arr.Cast<int>().Max(); //or Min

This seems to work:
IEnumerable<int> allValues = myArray.Cast<int>();
int min = allValues.Min();
int max = allValues.Max();

here is variant:
var maxarr = (from int v in aarray select v).Max();
where aarray is int[,]

You could implement a List<List<type>> and find the min and max in a foreach loop, and store it to a List. Then you can easily find the Min() and Max() from that list of all the values in a single-dimensional list.
That is the first thing that comes to mind, I am curious of this myself and am gonna see if google can grab a more clean cut approach.

Related

Is there a way to use similar method to OpenCv's MinMaxLoc to get a list of n max values instead of only one max value?

MinMaxLoc returns min and max values of a given input array, however I would like to gent the n max values of that array?
Is the only way to do a loop, if so how to to do it using OpenCvSharp?
My image is something like:
Here's how I would do it in python (my c# is rusty and I couldn't find anything on google about how to find the n largest elements in OpenCvSharp).
data = [[1,2,3],[4,5,6],[7,8,9]]
# first, collapse the 2 dimensional input into 1 dimension
collapsed_data = []
for row in data:
collapsed_data.extend(row)
# now sort the collapsed input and get the 5 largest elements
sorted_data = sorted(collapsed, reverse=True)
k_largest = sorted_data[:k]
Note, there are more efficient ways to do this using min/max heaps but that's a lot of code to write and i'm not sure if you need the performance. If you do, those solutions are a google away.
Assuming you have a rectangular array you can get the n max values by:
var numValuesToGet = 2;
var inputArray = new int[,] {{1,2},{3,4},{5,6}};
var result = inputArray.Cast<int>().OrderByDescending(x=>x).Take(numValuesToGet);
Likewise, you could get the n min values by replacing OrderByDescending with OrderBy.

How to find an item in an array that sum of all values before that is a spcific value? (C++ and C#)

Assume that I have an array of integers with a specific size (say 1000)
I want to find the index of an item in this array, given the sum of all items in the array before this item (or including this item).
for example assume that I have the following array:
int[] values={1,2,3,1,3,6,4,8,2,11}
Input value is 6, then I need to return the index 2 (zero based indexing for 3 in above example) and when given 10, I should return the index 4.
What is the fastest way to do this? in C++ and c#?
If you need to do it only once, then the naive way is also the fastest way: walk the array, and keep the running total. Once you reach the target sum, return the current index.
If you need to run multiple queries for different sums, create an array and set up sums in it, like this:
var sums = new int[values.Length];
sums[0] = values[0];
for (int i = 1 ; i < sums.Length ; i++) {
sums[i] = sums[i-1] + values[i];
}
If all values are positive, you can run binary search on sums to get to the index in O(log(n)).
learn BST, it's will the fastest algo for your problem:
http://en.wikipedia.org/wiki/Binary_search_tree

c# Leaner way of initializing int array

Having the following code is there a leaner way of initializing the array from 1 to the number especified by a variable?
int nums=5;
int[] array= new int[nums];
for(int i=0;i<num;i++)
{
array[i] = i;
}
Maybe with linq or some array.function?
int[] array = Enumerable.Range(0, nums).ToArray();
Use Enumerable.Range() method instead of. Don't forget to add System.Linq namespace. But this could spend little bit high memory. You can use like;
int[] array = Enumerable.Range(0, nums).ToArray();
Generates a sequence of integral numbers within a specified range.
Using Enumerable.Range
int[] array = Enumerable.Range(0, nums).ToArray();
Maybe I'm missing something here, but here is the best way I know of:
int[] data = new int [] { 383, 484, 392, 975, 321 };
from MSDN
even simpler:
int[] data = { 383, 484, 392, 975, 321 };

Compare arrays of int in high performance

I cant remember from my days in college, the way to compare two unsorted arrays of int and find the number of matches ?
Each value is unique in it own array, and both arrays are the same size.
for example
int[5] a1 = new []{1,2,4,5,0}
int[5] a2 = new []{2,4,11,-6,7}
int numOfMatches = FindMatchesInPerformanceOfNLogN(a1,a2);
any one does remember ?
If you can store the contents of one of the arrays in a HashMap, then you can check for the existence of the elements in the other array by seeing if they exist in the HashMap. This is O(n).
One array must be sorted so that you can compare in n*log(n). That is for every item in the unsorted array (n) you perform a binary search on the sorted array (log(n)). If both are unsorted, I don't see a way to compare in n*log(n).
how about this:
concatenate the two arrays
quicksort the result
step through from array[1] to array[array.length - 1] and check array[i] against array[i-1]
if they are the same, you had a duplicate. This should also be O(n*log(n)) and will not require a binary search for each check.
You could use LINQ:
var a1 = new int[5] {1, 2, 4, 5, 0};
var a2 = new int[5] {2, 4, 11, -6, 7};
var matches = a1.Intersect(a2).Count();
I'm not sure if you're just asking for a straight-forward way or the fastest/best way possible...
You have two methods that I am aware of (ref: http://www2.cs.siu.edu/~mengxia/Courses%20PPT/220/carrano_ppt08.ppt):
Recursive (pseudocode)
Algorithm to search a[first] through a[last] for desiredItem
if (there are no elements to search)
return false
else if (desiredItem equals a[first])
return true
else
return the result of searching a[first+1] through a[last]
Efficiency
May be O(log n) though I have not tried it.
Sequential Search (pseudocode)
public boolean contains(Object anEntry)
{
boolean found = false;
for (int index = 0; !found && (index < length); index++) {
if (anEntry.equals(entry[index]))
found = true;
}
return found;
}
Efficiency of a Sequential Search
Best case O(1)
Locate desired item first
Worst case O(n)
Must look at all the items
Average case O(n)
Must look at half the items
O(n/2) is still O(n)
I am not aware of an O(log n) search algorithm unless it is sorted.
I don't know if it is the fastest way but you can do
int[] a1 = new []{1,2,4,5,0};
int[] a2 = new []{2,4,11,-6,7};
var result = a1.Intersect(a2).Count();
It is worth comparing this with other ways that are optimised for int as Intersect() operates on IEnumerable.
This problem is also amenable to parallelization: spawn n1 threads and have each one compare an element of a1 with n2 elements of a2, then sum values. Probably slower, but interesting to consider, is spawning n1 * n2 threads to do all comparisons simultaneously, then reducing. If P >> max(n1, n2) in the first case, P >> n1 * n2 in the second, you could do the whole thing in O(n) in the first case, O(log n) in the second.

How can I count the unique numbers in an array without rearranging the array elements?

I am having trouble counting the unique values in an array, and I need to do so without rearranging the array elements.
How can I accomplish this?
If you have .NET 3.5 you can easily achieve this with LINQ via:
int numberOfElements = myArray.Distinct().Count();
Non LINQ:
List<int> uniqueValues = new List<int>();
for(int i = 0; i < myArray.Length; ++i)
{
if(!uniqueValues.Contains(myArray[i]))
uniqueValues.Add(myArray[i]);
}
int numberOfElements = uniqueValues.Count;
This is a far more efficient non LINQ implementation.
var array = new int[] { 1, 2, 3, 3, 3, 4 };
// .Net 3.0 - use Dictionary<int, bool>
// .Net 1.1 - use Hashtable
var set = new HashSet<int>();
foreach (var item in array) {
if (!set.Contains(item)) set.Add(item);
}
Console.WriteLine("There are {0} distinct values. ", set.Count);
O(n) running time max_value memory usage
boolean[] data = new boolean[maxValue];
for (int n : list) {
if (data[n]) counter++
else data[n] = true;
}
Should only the distinct values be counted or should each number in the array be counted (e.g. "number 5 is contained 3 times")?
The second requirement can be fulfilled with the starting steps of the counting sort algorithm.
It would be something like this:
build a set where the index/key is
the element to be counted
a key is connected to a variable which holds the number of occurences
of the key element
iterate the array
increment value of key(array[index])
Regards

Categories