how to get the array containing minimum difference array elements - c#

[Image of the actual problem]
we have to choose the best item/items based on input3 which is items to be selected. the choice should be such that we don't take maximum item always. Instead we take items which are not having much difference.
input1: total items
input2: array of items
input3: items to be selected
Scenario 1:
input: 6, {44,55,605,100,154,190}, 1
output should be: {605}
input: 5, {15,85,32,31,2}, 2
output should be: {32,31}
as we increase the number of items to be selected, output should have more item in selected with minimum difference.
Below is the code i am trying, i am new to this please help:
i am stuck how to make this dynamic.
public static int[] Find(int totalItems, int[] values, int totalToBeSelected)
{
var i = values;
int[] results = new int[totalToBeSelected];
var resultList = new List<int>();
if (totalToBeSelected == 1)
{
resultList.Add(values.Max());
return resultList.ToArray();
}
Array.Sort(i);
var minmumDiff = (i[0] - i[1]) * -1;
for (int k = 1; k < i.Length; k++)
{
var differnce = i[k] - i[k - 1];
if (differnce < minmumDiff)
{
resultList.Add(i[k]);
resultList.Add(i[k - 1]);
minmumDiff = differnce;
}
}
return resultList.ToArray();
}

You can look at this function.
public static int[] Find(int totalItems, int[] values, int totalToBeSelected)
{
Array.Sort(values);
Array.Reverse(values); // We need any value greater than max items diff. Max array item (first item after the sort) enough for it.
int diff = values[0];
int indx = 0;
for (int i = 0; i < totalItems - totalToBeSelected +1; i++)
{
int temp_diff = values[i] - values[i + totalToBeSelected - 1]; // We are looking for any items group that max and min value difference is minimum
if (temp_diff < diff )
{
diff = temp_diff;
indx = i;
}
}
int[] results = new int[totalToBeSelected];
Array.Copy(values, indx, results, 0, totalToBeSelected);
return results;
}
Sample:
Find( 6, new int[] { 44, 55, 605, 100, 154, 190 }, 1 );
Out: { 605 }
Find( 5, new int[] { 15, 85, 32, 31, 2 }, 2 );
Out: { 32, 31 }

The conditions in the question are unclear, some assumptions had to be made.
class Program
{
static void Main(string[] args)
{
var items = new[] {12,14,22,24,6};//new[] { 15, 85, 32, 31, 2};//new[] { 44, 55, 605, 100, 154, 190 };
var totalItems = items.Count();
var numberOfItemsToSelect = 3;
var result = Find(totalItems, items, numberOfItemsToSelect);
PrintList(result);
Console.ReadLine();
}
static void PrintList(IEnumerable<int> scoreList)
{
foreach (var score in scoreList)
{
Console.Write(score);
Console.Write(" ");
}
}
public static int[] Find(int totalItems, int[]values, int totalTobeSelected)
{
var result = new List<int>();
if (totalTobeSelected <= 1)
{
result.Add(values.Max());
}
else if (totalTobeSelected == totalItems)
{
result.AddRange(values.OrderBy(i => i).ToList());
}
else
{
var mainSet = values.OrderBy(i => i).ToList();
var setDic = new Dictionary<int, IEnumerable<int>>();
for (int i = 0; (totalItems - i >= totalTobeSelected); i++)
{
var set = mainSet.GetRange(i, totalTobeSelected);
//Inside a set, we choose the difference between the first and the second number
// ex: set = {2, 4, 9} => diff = |2-4| = 2.
var diff = Math.Abs(set[0] - set[1]);
// given two sets with the same diff, we select the first one base on the sort order of the main set:
// ex: main set = {2,4,8,10}. Both {2,4} and {6,8} have a diff of 2 so we select {2,4}
if (setDic.ContainsKey(diff)) continue;
setDic.Add(diff, set);
}
if (setDic.Count > 0)
{
var minKey = setDic.Keys.Min();
result.AddRange(setDic[minKey]);
}
}
return result.ToArray();
}
}

Related

Separating values in list when it decrease and increase

This is what I would like to do.
I have huge number of number in a list, but it has a sequence of either increasing or decreasing.
Such as,
100
200
300
400
500
600
500
400
300
200
100
500
700
800
900
Lets say this values are stored in a list or maybe an array. How could I separate these to multiple arrays or list consisting of the sequence.
Such as, List 1: 100 200 300 400 500 600
List 2 :500 400 300 200 100
List 3:500 700 800 900
This is what I have done. I am stuck.
for (int i = 0; i < p.Count - 1; i++)
{
double v = p.ElementAt(i);
if (initialP > v)
{
if (low == 1)
{
sep.Add(sep_index);
low = 0;
}
else
{
}
high = 1;
}
if (initialP < v)
{
if (high == 1)
{
sep.Add(sep_index);
high = 0;
}
low = 1;
}
initialP = v;
sep_index++;
if (i == p.Count - 2)
{
sep.Add(sep_index);
}
}
As suggested in the comments, you should use a list of of lists and while looping use a new list when there is a switch in the direction of the sort:
EDIT: Fixed to take into account equal numbers and strict comparaisons.
public static List<List<int>> GetLists(int[] nums, bool strict) {
List<List<int>> lists = new List<List<int>>();
List<int> list = new List<int>();
lists.Add(list);
list.AddRange(nums.Take(1));
if (nums.Length <= 1) {
return lists;
}
if (strict && nums[0] == nums[1]) {
list = new List<int>();
lists.Add(list);
list.Add(nums[1]);
}
else
list.Add(nums[1]);
if (nums.Length == 2)
{
return lists;
}
int direction = Math.Sign(nums[2] - nums[1]);
for (int i = 2; i < nums.Length; i++) {
int d = Math.Sign(nums[i] - nums[i - 1]);
if ((d == direction && (d != 0 || !strict))
|| (d != 0 && strict)
|| (Math.Abs(d + direction) == 1 && !strict))
{
list.Add(nums[i]);
if (d != 0 && direction == 0) direction = d;
}
else
{
direction = d;
list = new List<int>();
list.Add(nums[i]);
lists.Add(list);
}
}
return lists;
}
static void Main(string[] args)
{
int[] nums = new int[] { 2, 2, 2, 1, 1, 3, 3, 4, 4 };
var lists = GetLists(nums, false);
foreach (var list in lists) {
foreach (var item in list)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
/*
* Prints:
* 2 2 2 1 1
* 3 3 4 4
* */
}
Derivation, or spin. If it is positive -- one direction. Otherwise -- another.
Use spin, which will show you direction (up or down): (n+1/n). When spin changes, then store elements in a list.
Possible solution:
public static IList<IList<int>> UpDownSeparator(IEnumerable<int> value) {
if (Object.ReferenceEquals(null, value))
throw new ArgumentNullException("value");
List<IList<int>> result = new List<IList<int>>();
List<int> current = new List<int>();
result.Add(current);
// +1 - asceding, -1 - descending, 0 - to be determined later
int direction = 0;
foreach(int item in value) {
if (direction == 0) {
if (current.Count > 0) {
if (item > current[current.Count - 1])
direction = 1;
else if (item < current[current.Count - 1])
direction = -1;
}
current.Add(item);
}
else if (direction < 0) {
if (item > current[current.Count - 1]) {
direction = 1;
current = new List<int>() { item };
result.Add(current);
}
else
current.Add(item);
}
else {
if (item < current[current.Count - 1]) {
direction = -1;
current = new List<int>() { item };
result.Add(current);
}
else
current.Add(item);
}
}
return result;
}
....
List<int> list = new List<int>() { 100, 200, 300, 400, 500, 600, 500, 400, 300, 200, 100, 500, 700, 800, 900};
// [[100, 200, 300, 400, 500, 600], [500, 400, 300, 200, 100], [500, 700, 800, 900]]
IList<IList<int>> result = UpDownSeparator(list);
I would do something like this:
private static List<int[]> SplitOnDirection(int[] input)
{
List<int[]> output = new List<int[]>();
List<int> currentList = new List<int>();
bool? isRaising = null;
int? previousNumber = null;
foreach (int number in input)
{
// do we have a previous value?
if (previousNumber.HasValue)
{
// only if the number is different, then we have to check the direction.
if (number != previousNumber.Value)
{
bool isHigherNumber = (number > previousNumber.Value);
// do we already know if we start with raise/lowering
if (isRaising.HasValue)
{
// if we have a higher number and we're not raising, change direction.
if (isHigherNumber != isRaising.Value)
{
// We changed direction..
output.Add(currentList.ToArray());
currentList = new List<int>();
}
}
isRaising = isHigherNumber;
}
}
previousNumber = number;
currentList.Add(number);
}
// if we didn't changed direction, we should 'flush' these.
if (currentList.Count > 0)
output.Add(currentList.ToArray());
return output;
}
int[] input = new int[] { 100, 200, 300, 400, 500, 600, 500, 400, 300, 200, 100, 500, 700, 800, 900 };
List<int[]> output = SplitOnDirection(input);
Took around 20 min, but I would do something like this below. Using Java, I am sure could easily be written using other language syntax.
Input
1, 1, 1, -1, 2, 3, 4, 4, 4, 5, 6, 5, 4, 4, 3, 3, 6, 6, 2, 1, 5, 7, 8, 9
Output
1 1 1 -1
2 3 4 4 4 5 6
5 4 4 3 3
6 6
2 1
5 7 8 9
Code
public static void main(String[] args) {
int[] input = new int[]{1, 1, 1, -1, 2, 3, 4, 4, 4, 5, 6, 5, 4, 4, 3, 3, 6, 6, 2, 1, 5, 7, 8, 9};
List<List<Integer>> lists = split(input);
for (List<Integer> list : lists) {
for (Integer integer : list) {
System.out.print(integer+" ");
}
System.out.println("");
}
}
public static List<List<Integer>> split(int[] input) {
List<List<Integer>> listOfList = new ArrayList<List<Integer>>();
if(input.length >= 1) {
List<Integer> list = newList(listOfList, input[0]);
Order lastO = null;
int last = input[0];
for (int i = 1; i < input.length; i++) {
Order currentO = Order.getOrder(input[i], last);
boolean samePattern = Order.sameDirection(currentO, lastO);
if(lastO == null || samePattern) {
list.add(input[i]);
} else {
list = newList(listOfList, input[i]);
lastO = null;
}
if(currentO != Order.Equal){
lastO = currentO;
}
last = input[i];
}
}
return listOfList;
}
private static List<Integer> newList(List<List<Integer>> listOfList, int element) {
List<Integer> list = new ArrayList<Integer>();
listOfList.add(list);
list.add(element);
return list;
}
private static enum Order {
Less, High, Equal;
public static Order getOrder(int first, int second) {
return first > second ? High : first < second ? Less : Equal;
}
public static boolean sameDirection(Order current, Order last) {
if(last == Order.Less && (current == Order.Less || current == Order.Equal)) {
return true;
} else if(last == Order.High && (current == Order.High || current == Order.Equal)) {
return true;
}
return false;
}
}

Finding all numbers that sum to a specified target number (integer partition)

First i want to say i'm still learning so my programming skills are not very good, and i'm willing to accept any advice you have.
Second i'm still learning english so i want to say sorry for the inconvenience.
Well my problem is this, i need help improving my algorithm or any information about it, i don't know what words use for searching this.
The algorithm is supposed to find all the combinations of numbers that added is equal to a given number. Example: if i have the number 6 my results are supposed to be: [1,5],[2,4],[2,2,2],[3,3]
i have the following:
public List<List<int>> discompose(int number)
{
List<List<int>> discomposedPairs = new List<List<int>>();
if (number <= 3)
return discomposedPairs;
int[] numsForCombine = new int[number-1];
for(int i = 1; i < number;i++){
numsForCombine[i - 1] = i;
}
int ini = 0;
int end = numsForCombine.Length - 1;
while (ini <= end)
{
List<int> pair = new List<int>();
pair.Add(numsForCombine[ini++]);
pair.Add(numsForCombine[end--]);
discomposedPairs.Add(pair);
}
return discomposedPairs;
}
public List<List<int>> discomposePair(List<int> pair)
{
List<List<int>> parDisc = new List<List<int>>();
for (int i = 0; i < pair.Count; i++) {
if (pair[i] > 3)
{
List<List<int>> disc = discomposeList(discompose(pair[i]));
foreach (List<int> item in disc)
{
if (i > 0)
{
var temp = pair.GetRange(0, i);
temp.AddRange(item);
parDisc.Add(temp);
} else {
item.AddRange(pair.GetRange(i+1, pair.Count-(i+1)));
parDisc.Add(item);
}
}
}
}
return parDisc;
}
public List<List<int>> discomposeList(List<List<int>> list)
{
List<List<int>> mainDiscomposedList = new List<List<int>>();
for (int i = 0; i < list.Count; i++)
{
mainDiscomposedList.Add(list[i]);
List<List<int>> discomposedSubset = discomposePair(list[i]);
foreach(List<int> item in discomposedSubset){
mainDiscomposedList.Add(item);
}
}
return mainDiscomposedList;
}
The first method descompose the number given in pairs that added are equal the number given.
The second and the third method are the ugliest they are recursive and have bucles so they don't have any good performance. Between the two generates a List with numbers as i the problem says but there are a few inconvenients:
1) Don't have good performance
2) Gives a lot of repetitive sequences
here is the output for the number 10
[2,8,]
[2,2,6,]
[2,2,2,4,]
[2,2,2,2,2,]
[2,2,3,3,]
[2,3,5,]
[2,3,2,3,]<-------------repeated
[2,4,4,]
[2,2,2,4,]<-------------repeated
[2,4,2,2,]<-------------repeated
[3,7,]
[3,2,5,]<-------------repeated
[3,2,2,3,]<-------------repeated
[3,3,4,]
[3,3,2,2,]
[4,6,]
[2,2,6,]<-------------repeated
[4,2,4,]<-------------repeated
[4,2,2,2,]<-------------repeated
[4,3,3,]<-------------repeated
[5,5,]
[2,3,5,]<-------------repeated
[5,2,3,]<-------------repeated
Finally i want to improve the performance and have the less possible repeated items being a repeated item [1,1,3], [1,3,1], [3,1,1]
[Here is the full project link]1
Here's one approach that first builds the combinations into a tree structure, then arranges them into lists of ints:
internal class Combination
{
internal int Num;
internal IEnumerable<Combination> Combinations;
}
internal static IEnumerable<Combination> GetCombinationTrees(int num, int max)
{
return Enumerable.Range(1, num)
.Where(n => n <= max)
.Select(n =>
new Combination
{
Num = n,
Combinations = GetCombinationTrees(num - n, n)
});
}
internal static IEnumerable<IEnumerable<int>> BuildCombinations(
IEnumerable<Combination> combinations)
{
if (combinations.Count() == 0)
{
return new[] { new int[0] };
}
else
{
return combinations.SelectMany(c =>
BuildCombinations(c.Combinations)
.Select(l => new[] { c.Num }.Concat(l))
);
}
}
public static IEnumerable<IEnumerable<int>> GetCombinations(int num)
{
var combinationsList = GetCombinationTrees(num, num);
return BuildCombinations(combinationsList);
}
public static void PrintCombinations(int num)
{
var allCombinations = GetCombinations(num);
foreach (var c in allCombinations)
{
Console.WriteLine(string.Join(", ", c));
}
}
When run with the input value 6, this produces:
1, 1, 1, 1, 1, 1
2, 1, 1, 1, 1
2, 2, 1, 1
2, 2, 2
3, 1, 1, 1
3, 2, 1
3, 3
4, 1, 1
4, 2
5, 1
6

C# find highest array value and index

So I have an unsorted numeric array int[] anArray = { 1, 5, 2, 7 }; and I need to get both the value and the index of the largest value in the array which would be 7 and 3, how would I do this?
This is not the most glamorous way but works.
(must have using System.Linq;)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
int[] anArray = { 1, 5, 2, 7 };
// Finding max
int m = anArray.Max();
// Positioning max
int p = Array.IndexOf(anArray, m);
If the index is not sorted, you have to iterate through the array at least once to find the highest value. I'd use a simple for loop:
int? maxVal = null; //nullable so this works even if you have all super-low negatives
int index = -1;
for (int i = 0; i < anArray.Length; i++)
{
int thisNum = anArray[i];
if (!maxVal.HasValue || thisNum > maxVal.Value)
{
maxVal = thisNum;
index = i;
}
}
This is more verbose than something using LINQ or other one-line solutions, but it's probably a little faster. There's really no way to make this faster than O(N).
A succinct one-liner:
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Test case:
var anArray = new int[] { 1, 5, 7, 4, 2 };
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Console.WriteLine($"Maximum number = {number}, on index {index}.");
// Maximum number = 7, on index 2.
Features:
Uses Linq (not as optimized as vanilla, but the trade-off is less code).
Does not need to sort.
Computational complexity: O(n).
Space complexity: O(n).
Remarks:
Make sure the number (and not the index) is the first element in the tuple because tuple sorting is done by comparing tuple items from left to right.
The obligatory LINQ one[1]-liner:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(The sorting is probably a performance hit over the other solutions.)
[1]: For given values of "one".
Here are two approaches. You may want to add handling for when the array is empty.
public static void FindMax()
{
// Advantages:
// * Functional approach
// * Compact code
// Cons:
// * We are indexing into the array twice at each step
// * The Range and IEnumerable add a bit of overhead
// * Many people will find this code harder to understand
int[] array = { 1, 5, 2, 7 };
int maxIndex = Enumerable.Range(0, array.Length).Aggregate((max, i) => array[max] > array[i] ? max : i);
int maxInt = array[maxIndex];
Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");
}
public static void FindMax2()
{
// Advantages:
// * Near-optimal performance
int[] array = { 1, 5, 2, 7 };
int maxIndex = -1;
int maxInt = Int32.MinValue;
// Modern C# compilers optimize the case where we put array.Length in the condition
for (int i = 0; i < array.Length; i++)
{
int value = array[i];
if (value > maxInt)
{
maxInt = value;
maxIndex = i;
}
}
Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");
}
int[] numbers = new int[7]{45,67,23,45,19,85,64};
int smallest = numbers[0];
for (int index = 0; index < numbers.Length; index++)
{
if (numbers[index] < smallest) smallest = numbers[index];
}
Console.WriteLine(smallest);
public static class ArrayExtensions
{
public static int MaxIndexOf<T>(this T[] input)
{
var max = input.Max();
int index = Array.IndexOf(input, max);
return index;
}
}
This works for all variable types...
var array = new int[]{1, 2, 4, 10, 0, 2};
var index = array.MaxIndexOf();
var array = new double[]{1.0, 2.0, 4.0, 10.0, 0.0, 2.0};
var index = array.MaxIndexOf();
this works like a charm, no need for linq or other extensions
int[] anArray = { 1, 5, 2, 7 };
int i, mx;
int j = 0;
mx = anArray[0];
for (i = 1; i < anArray.Length; i++)
{
if (anArray[i] > mx)
{
mx = anArray[i];
j = i;
}
}
Console.Write("The largest value is: {0}, of index: {1}", mx, j);
anArray.Select((n, i) => new { Value = n, Index = i })
.Where(s => s.Value == anArray.Max());
Output for bellow code:
00:00:00.3279270 - max1
00:00:00.2615935 - max2
00:00:00.6010360 - max3 (arr.Max())
With 100000000 ints in array not very big difference but still...
class Program
{
static void Main(string[] args)
{
int[] arr = new int[100000000];
Random randNum = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = randNum.Next(-100000000, 100000000);
}
Stopwatch stopwatch1 = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();
Stopwatch stopwatch3 = new Stopwatch();
stopwatch1.Start();
var max = GetMaxFullIterate(arr);
Debug.WriteLine( stopwatch1.Elapsed.ToString());
stopwatch2.Start();
var max2 = GetMaxPartialIterate(arr);
Debug.WriteLine( stopwatch2.Elapsed.ToString());
stopwatch3.Start();
var max3 = arr.Max();
Debug.WriteLine(stopwatch3.Elapsed.ToString());
}
private static int GetMaxPartialIterate(int[] arr)
{
var max = arr[0];
var idx = 0;
for (int i = arr.Length / 2; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
if (arr[idx] > max)
{
max = arr[idx];
}
idx++;
}
return max;
}
private static int GetMaxFullIterate(int[] arr)
{
var max = arr[0];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
public static void Main()
{
int a,b=0;
int []arr={1, 2, 2, 3, 3, 4, 5, 6, 5, 7, 7, 7, 100, 8, 1};
for(int i=arr.Length-1 ; i>-1 ; i--)
{
a = arr[i];
if(a > b)
{
b=a;
}
}
Console.WriteLine(b);
}
Old post, but this is super easy with Lists:
For Maximum:
List<int> lst = new List<int>(YourArray);
int Max = lst.OrderByDescending(x => x).First();
For Minimum:
List<int> lst = new List<int>(YourArray);
int Max = lst.OrderBy(x => x).First();
Of course you can substitute "int" data type with any numeric variable type (float, decimal, etc).
This is very high performance BTW and beats any other method (IMHO)
int[] Data= { 1, 212, 333,2,12,3311,122,23 };
int large = Data.Max();
Console.WriteLine(large);
Here is a LINQ solution which is O(n) with decent constant factors:
int[] anArray = { 1, 5, 2, 7, 1 };
int index = 0;
int maxIndex = 0;
var max = anArray.Aggregate(
(oldMax, element) => {
++index;
if (element <= oldMax)
return oldMax;
maxIndex = index;
return element;
}
);
Console.WriteLine("max = {0}, maxIndex = {1}", max, maxIndex);
But you should really write an explicit for lop if you care about performance.
Just another perspective using DataTable. Declare a DataTable with 2 columns called index and val. Add an AutoIncrement option and both AutoIncrementSeed and AutoIncrementStep values 1 to the index column. Then use a foreach loop and insert each array item into the datatable as a row. Then by using Select method, select the row having the maximum value.
Code
int[] anArray = { 1, 5, 2, 7 };
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("index"), new DataColumn("val")});
dt.Columns["index"].AutoIncrement = true;
dt.Columns["index"].AutoIncrementSeed = 1;
dt.Columns["index"].AutoIncrementStep = 1;
foreach(int i in anArray)
dt.Rows.Add(null, i);
DataRow[] dr = dt.Select("[val] = MAX([val])");
Console.WriteLine("Max Value = {0}, Index = {1}", dr[0][1], dr[0][0]);
Output
Max Value = 7, Index = 4
Find a demo here
If you know max index accessing the max value is immediate. So all you need is max index.
int max=0;
for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;
This is a C# Version. It's based on the idea of sort the array.
public int solution(int[] A)
{
// write your code in C# 6.0 with .NET 4.5 (Mono)
Array.Sort(A);
var max = A.Max();
if(max < 0)
return 1;
else
for (int i = 1; i < max; i++)
{
if(!A.Contains(i)) {
return i;
}
}
return max + 1;
}
Consider following:
/// <summary>
/// Returns max value
/// </summary>
/// <param name="arr">array to search in</param>
/// <param name="index">index of the max value</param>
/// <returns>max value</returns>
public static int MaxAt(int[] arr, out int index)
{
index = -1;
int max = Int32.MinValue;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
index = i;
}
}
return max;
}
Usage:
int m, at;
m = MaxAt(new int[]{1,2,7,3,4,5,6}, out at);
Console.WriteLine("Max: {0}, found at: {1}", m, at);
This can be done with a bodiless for loop, if we're heading towards golf ;)
//a is the array
int mi = a.Length - 1;
for (int i=-1; ++i<a.Length-1; mi=a[mi]<a[i]?i:mi) ;
The check of ++i<a.Length-1 omits checking the last index. We don't mind this if we set it up as if the max index is the last index to start with.. When the loop runs for the other elements it will finish and one or the other thing is true:
we found a new max value and hence a new max index mi
the last index was the max value all along, so we didn't find a new mi, and we stuck with the initial mi
The real work is done by the post-loop modifiers:
is the max value (a[mi] i.e. array indexed by mi) we found so far, less than the current item?
yes, then store a new mi by remembering i,
no then store the existing mi (no-op)
At the end of the operation you have the index at which the max is to be found. Logically then the max value is a[mi]
I couldn't quite see how the "find max and index of max" really needed to track the max value too, given that if you have an array, and you know the index of the max value, the actual value of the max value is a trivial case of using the index to index the array..
Another answer in this long list, but I think it's worth it, because it provides some benefits that most (or all?) other answers don't:
The method below loops only once through the collection, therefore the order is O(N).
The method finds ALL indices of the maximum values.
The method can be used to find the indices of any comparison: min, max, equals, not equals, etc.
The method can look into objects via a LINQ selector.
Method:
///-------------------------------------------------------------------
/// <summary>
/// Get the indices of all values that meet the condition that is defined by the comparer.
/// </summary>
/// <typeparam name="TSource">The type of the values in the source collection.</typeparam>
/// <typeparam name="TCompare">The type of the values that are compared.</typeparam>
/// <param name="i_collection">The collection of values that is analysed.</param>
/// <param name="i_selector">The selector to retrieve the compare-values from the source-values.</param>
/// <param name="i_comparer">The comparer that is used to compare the values of the collection.</param>
/// <returns>The indices of all values that meet the condition that is defined by the comparer.</returns>
/// Create <see cref="IComparer{T}"/> from comparison function:
/// Comparer{T}.Create ( comparison )
/// Comparison examples:
/// - max: (a, b) => a.CompareTo (b)
/// - min: (a, b) => -(a.CompareTo (b))
/// - == x: (a, b) => a == 4 ? 0 : -1
/// - != x: (a, b) => a != 4 ? 0 : -1
///-------------------------------------------------------------------
public static IEnumerable<int> GetIndices<TSource, TCompare> (this IEnumerable<TSource> i_collection,
Func<TSource, TCompare> i_selector,
IComparer<TCompare> i_comparer)
{
if (i_collection == null)
throw new ArgumentNullException (nameof (i_collection));
if (!i_collection.Any ())
return new int[0];
int index = 0;
var indices = new List<int> ();
TCompare reference = i_selector (i_collection.First ());
foreach (var value in i_collection)
{
var compare = i_selector (value);
int result = i_comparer.Compare (compare, reference);
if (result > 0)
{
reference = compare;
indices.Clear ();
indices.Add (index);
}
else if (result == 0)
indices.Add (index);
index++;
}
return indices;
}
If you don't need the selector, then change the method to
public static IEnumerable<int> GetIndices<TCompare> (this IEnumerable<TCompare> i_collection,
IComparer<TCompare> i_comparer)
and remove all occurences of i_selector.
Proof of concept:
//########## test #1: int array ##########
int[] test = { 1, 5, 4, 9, 2, 7, 4, 6, 5, 9, 4 };
// get indices of maximum:
var indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a.CompareTo (b)));
// indices: { 3, 9 }
// get indices of all '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 4 ? 0 : -1));
// indices: { 2, 6, 10 }
// get indices of all except '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a != 4 ? 0 : -1));
// indices: { 0, 1, 3, 4, 5, 7, 8, 9 }
// get indices of all '15':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 15 ? 0 : -1));
// indices: { }
//########## test #2: named tuple array ##########
var datas = new (object anything, double score)[]
{
(999, 0.1),
(new object (), 0.42),
("hello", 0.3),
(new Exception (), 0.16),
("abcde", 0.42)
};
// get indices of highest score:
indices = datas.GetIndices (data => data.score, Comparer<double>.Create ((a, b) => a.CompareTo (b)));
// indices: { 1, 4 }
Enjoy! :-)
Finds the biggest and the smallest number in the array:
int[] arr = new int[] {35,28,20,89,63,45,12};
int big = 0;
int little = 0;
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
if (arr[i] > arr[0])
{
big = arr[i];
}
else
{
little = arr[i];
}
}
Console.WriteLine("most big number inside of array is " + big);
Console.WriteLine("most little number inside of array is " + little);

How to find highest ,second highest number, Lowest Second Lowest number in given Array

Can anyone Please tell me how to How to find highest ,second highest number, Lowest Second Lowest number in given Array
var numbers = new[] {855,3,64,6,24,75,3,6,24,45};
Any pointer and suggestion would really helpful . Thanks
You can also try this -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class secondHighestLowest : System.Web.UI.Page
{
int[] arr = new int[10] { 45, 3, 64, 6, 24, 75, 3, 6, 24, 45 };
protected void Page_Load(object sender, EventArgs e)
{
secondHighestLowestNumber();
secoundLowestNumber();
}
private void secondHighestLowestNumber()
{
int firstHighestNumber = arr[0];
int secondHighestNumber = arr[0];
for(int i = 0; i<arr.Length; i++)
{
if (arr[i]>firstHighestNumber)
{
firstHighestNumber = arr[i];
}
}
for (int x = 0; x < arr.Length; x++)
{
if (arr[x]>secondHighestNumber && firstHighestNumber!=arr[x])
{
secondHighestNumber = arr[x];
}
}
Response.Write("secondHighestNumber---- " + secondHighestNumber + "</br>");
}
private void secoundLowestNumber()
{
int firstLowestNumber = arr[0];
int secondLowestNumber = arr[0];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] < firstLowestNumber)
{
firstLowestNumber = arr[i];
}
}
for (int x = 0; x < arr.Length; x++)
{
if (arr[x] < secondLowestNumber && firstLowestNumber != arr[x])
{
secondLowestNumber = arr[x];
}
}
Response.Write("secondLowestNumber---- " + secondLowestNumber + "</br>");
}
}
Hope this is helpful :)
You don't specify the complexity requirement: one way is to sort the array in descending order and pick the top, second and third items.
Another is to build a Heap, and then perform remove root 3 times (with the heap being rebuilt after each remove).
Assuming you have at least 2 items in the array you can use OrderBy() and ElementAt():
var numbers = new[] { 855, 3, 64, 6, 24, 75, 3, 6, 24, 45 };
var secondLowest = numbers.OrderBy(num => num).ElementAt(1);
var secondHighest = numbers.OrderBy(num => num).Reverse().ElementAt(1);
Getting the highest and lowest is simpler and can be done using Max() and Min() LINQ methods.
var lowest = numbers.Min();
var highest = numbers.Max();
If you're worried about complexity, you can achieve better result using Selection algorithm. Using it you can perform the operations in O(n) complexity.
Using Linq Concepts
var a = new int[] { 855, 3, 64, 6, 24, 75, 3, 6, 24, 45 };
var Max = a.Max(z => z);
var Min = a.Min( z => z);
var SMax = a.OrderByDescending(z=>z).Skip(1).First();
var SMin = a.OrderBy(z => z).Skip(1).First();
int[] i = new int[] { 4, 8, 1, 9, 2, 7, 3 };
Array.Sort(i);
Console.WriteLine("Highest number :" + i[i.Length-1]);
Console.WriteLine("Second highest number :"+i[i.Length-2]);
Console.WriteLine("Lowest number :" + i[i.Length-i.Length]);
Console.WriteLine("Second Lowest number :" + i[i.Length -i.Length+1]);
Output : Highest number : 9
Second highest number : 8
Lowest number : 1
Second Lowest number : 2
Why two loops when can be done in
int[] myArray = new int[] { 2, 4, 3, 6, 9 };
int max1 = 0;
int max2 = 0;
for (int i = 0; i < myArray.Length; i++)
{
if (myArray[i] > max1)
{
max2 = max1;
max1 = myArray[i];
}
else
{
max2 = myArray[i];
}
}
Console.WriteLine("first" + max1.ToString());
Console.WriteLine("Second" + max2.ToString());
Console.ReadKey();
I have first arranged them using Selection Sort algorithm in ascending order, then i displayed values.
static void Main(string[] args)
{
int[] Num =new int[] { 3, 4, 5, 6, 7, 0,99,105,55 };
int temp;
for(int a=0;a<Num.Length-1;a++)
{
for(int b=a+1;b<Num.Length;b++)
{
if(Num[a]>Num[b])
{
temp = Num[a];
Num[a] = Num[b];
Num[b] = temp;
}
}
}
Console.WriteLine("Max value ="+Num[Num.Length-1]+"\nSecond largest Max value="+ Num[Num.Length - 2]+"\nMin value =" + Num[0] + "\nSecond smallest Min value=" + Num[1]);
Console.WriteLine("\nPress to close");
Console.ReadLine();
}
This algorithm is applicable even with duplicate record.
int[] intArrayInput= new int[] { 855, 3, 64, 6, 24, 75, 3, 6, 24, 45, 855 };
Using Sort:
Array.Sort(intArrayInput);
int intMax = intArrayInput[intInput.Length - 1];
int intLow = intArrayInput[0];
And using LINQ:
int intSecondMax = intArrayInput.OrderByDescending(x => x).Distinct().Skip(1).First();
int intSecondLow = intArrayInput.OrderBy(x => x).Distinct().Skip(1).First();
Here is an easy solution assuming you array has at least two members.
For the lowest number in the array.
Array.Sort(new);
string newNumber = string.Join(" ", new[0]);
return newNumber;
For second lowest number in the array.
Array.Sort(new);
string newNumber = string.Join(" ", new[1]);
return newNumber;
for the highest number in the array.
Array.Sort(new);
string newNumber = string.Join(" ", new[new.Length - 1]);
return newNumber;
For the second highest number in the array.
Array.Sort(new);
string newNumber = string.Join(" ", new[new.Length - 1]);
return newNumber;
Shortest way to find out largest, second largest, smallest & second smallest number, using conventional method:
int LargestNumber = 0;
int SecondLargestNumber = 0;
int SmallestNumber = 0;
int SecondSmallestNumber = 0;
int[] array = new int[] { 250, 5, 17, 50, 98, 352, 2, 8, 67, 150, 200, 1 };
for (int i = 0; i < array.Length; i++)
{
if (array[i] > LargestNumber)
{
SecondLargestNumber = LargestNumber;
LargestNumber = array[i];
}
else if (array[i] > SecondLargestNumber)
{
SecondLargestNumber = array[i];
}
if (i == 0)
{
SmallestNumber = array[0];
SecondSmallestNumber = array[1];
}
if (array[i] < SmallestNumber)
{
SecondSmallestNumber = SmallestNumber;
SmallestNumber = array[i];
}
else if (array[i] < SecondSmallestNumber)
{
SecondSmallestNumber = array[i];
}
}
Console.WriteLine("Largest Number : " + LargestNumber);
Console.WriteLine("Second Largest Number : " + SecondLargestNumber);
Console.WriteLine("Smallest Number : " + SmallestNumber);
Console.WriteLine("Second Smallest Number : " + SecondSmallestNumber);
int[] myUnSortArray = { 1, 5, 8, 3, 10, 6, 19, 5, 4, 4 };
int[] SortedArray = (from number in myUnSortArray
orderby number ascending
select number).ToArray();
int highestValue = SortedArray.Max();
int SecondHighest = SortedArray.Last(m => m < highestValue);

How to get the second highest number in an array in Visual C#?

I have an array of ints. I want to get the second highest number in that array. Is there an easy way to do this?
Try this (using LINQ):
int secondHighest = (from number in numbers
orderby number descending
select number).Skip(1).First();
You could sort the array and choose the item at the second index, but the following O(n) loop will be much faster.
int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5 };
int largest = int.MinValue;
int second = int.MinValue;
foreach (int i in myArray)
{
if (i > largest)
{
second = largest;
largest = i;
}
else if (i > second)
second = i;
}
System.Console.WriteLine(second);
Yes, have 2 vars (first and second) passthrough the array and each time compair what you get with this two cells (always putting the highest on first and the 2nd highest on second)
with one pass you will get the 2nd higher on the second var.
You don't specify if you want to do this with the minimum complexity.
Assuming your array is unsorted, please see: How to find the kth largest element in an unsorted array of length n in O(n)?
To find Kth largest element in an unsorted array: Build a max heap in O(n). Now remove k elements from the heap; where each removal costs log(n) time to maintain the heap. Total time complexity = O(n + klogn)
To understand building Max heap in O(n) see Binary heap
max1=0;
max2=0;
for( int i=0; i < a.Length; i++)
{
if (arr[i]> max1)
{
max2=max1;
max1=arr[i];
}
else
{
if (a[i]!= max1) && ( a[i] > max2)
max2[i]=arr[i];
}
}
Getting the max number first, once the max is changed do a comparison against the second high number to see if it needs to swapped. The second if statement checks if the value is less than the max and is greater than the second highest value. Because of the short circuit, if the first condition fails then it exits the if and skips
static void Main(string[] args)
{
//int[] arr = new int[10] { 9, 4, 6, 2, 11, 100, 53, 23, 72, 81 };
int[] arr = { 1, 8, 4, 5, 12, 2, 5, 6, 7, 1, 90, 100, 56, 8, 34 };
int MaxNum = 0;
int SecNum = 0;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > MaxNum)
{
if (MaxNum > SecNum) { SecNum = MaxNum; }
MaxNum = arr[i];
}
if (arr[i] < MaxNum && arr[i] > SecNum)
{
SecNum = arr[i];
}
}
Console.WriteLine("Highest Num: {0}. Second Highest Num {1}.", MaxNum, SecNum);
Console.ReadLine();
}
int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5 };
int num1=0, temp=0;
for (int i = 0; i < myArray.Length; i++)
{
if (myArray[i] >= num1)
{
num1 = myArray[i];
}
else if ((myArray[i] < num1) && (myArray[i] > temp))
{
temp = myArray[i];
}
}
Console.WriteLine("The Largest Number is: " + num1);
Console.WriteLine("The Second Highest Number is: " + temp);
int[] arr = { 1, 8, 4, 5, 12, 2, 5, 6, 7, 1, 90, 100, 56, 8, 34 };
int first, second;
// Assuming the array has at least one element:
first = second = arr[0];
for(int i = 1; i < arr.Length; ++i)
{
if (first < arr[i])
{
// 'first' now contains the 2nd largest number encountered thus far:
second = first;
first = arr[i];
}
}
MessageBox.Show(second.ToString());
static void Main(string[] args)
{
int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5,12,11,14 };
int num1 = 0, temp = 0;
for (int i = 0; i < myArray.Length; i++)
{
if (myArray[i] >= num1)
{
temp = num1;
num1 = myArray[i];
}
else if ((myArray[i] < num1) && (myArray[i] > temp))
{
temp = myArray[i];
}
}
Console.WriteLine("The Largest Number is: " + num1);
Console.WriteLine("The Second Highest Number is: " + temp);
Console.ReadKey();
}
There are two possibilities to find second highest number from an array.
1). Find second max number from an array.
int[] myArray = { 0, 2, 3, 8, 13};
int max = 0;
int second_max = 0;
foreach (int arr in myArray) {
if (arr > max)
{
second_max = max;
max = arr;
}
}
Console.WriteLine("First highest number is: "+max);
Console.WriteLine("Second highest number is: " + second_max);
2). Find second max number with the smallest complexity from an array.
int[] myArray = { 0, 2, 3, 13, 8};//smaller number is given after
larger number
int max = 0;
int second_max = 0;
foreach (int arr in myArray) {
if (arr > max)
{
second_max = max;
max = arr;
}
else if (arr > second_max)
{
second_max = arr;
}
}
Console.WriteLine("First highest number is: "+max);
Console.WriteLine("Second highest number is: " + second_max);

Categories

Resources