If there are multiple string with same length(max), how do I find out all the indices. I am getting the first index currently. Is there a better way to do this?
using System;
using System.Linq;
namespace Examples
{
class Program
{
static void Main(string[] args)
{
Longestword("Find the largest word with lower index abcdefg ");
Console.ReadKey();
}
private static void Longestword(String sen)
{
String[] sArray = sen.Split(null);
int[] cArr = new int[sArray.Length];
for (int i = 0; i < sArray.Length; i++)
{
int j = sArray[i].Length;
cArr[i] = j;
}
int max = cArr.Max();
int index = cArr.ToList().IndexOf(max);
Console.WriteLine(index);
}
}
}
Here's my stab at a solution:
public static class LinqExtensions
{
public static List<int> IndicesOf(this int[] array, int item)
{
var indices = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] == item)
indices.Add(i);
}
return indices;
}
}
You can then call it like this:
int[] someArrayFindMax = new[] { 1, 4, 45, 23, 4, 3342, 34, 3342, 4, 3342, 3342 };
int max = someArrayFindMax.Max();
List<int> indices = someArrayFindMax.IndicesOf(max);
Here's another possible extension method for finding the indices of the longest strings directly:
public static List<int> LongestStringIndices(this string[] strings)
{
int longestString = -1;
var indices = new List<int>();
for (int i = 0; i < strings.Length; i++)
{
if (strings[i].Length > longestString)
{
longestString = strings[i].Length;
// We're no longer interested in the indices of the
// strings we now know to be shorter
indices.Clear();
indices.Add(i);
}
else if (strings[i].Length == longestString)
{
indices.Add(i);
}
// If it's less than the max length so far we ignore it
}
return indices;
}
I'd play with LINQ, as it's the C#-ish way.
Here's a fiddle: https://dotnetfiddle.net/NEFkqb
List<string> words = new List<string>{"aaaa","bb","cccc"};
List<int> lengths = words.Select(word => word.Length).ToList();
int max = lengths.Max();
List<int> maxes = new List<int>();
for(int i = 0; i < lengths.Count; i++)
if(lengths[i] == max)
maxes.Add(i);
Related
I am trying to find index of an array.Probably doing this is easy but I couldn't do that.I tried to add a function(findIndex),looking at a website but I am getting an error.How can I find the index?
namespace exmple.Filters
{
class dnm2
{
public static byte[] Shape(byte[] data)
{
byte[] shape = new byte[data.Length];
byte count = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0)
{
shape[i] = (data[i]);
int index = shape.findIndex(count);
int[] a = {1, 2, 3};
int index = a.Indexof((int)3);
count += 1;
}
}
return shape;
}
public static int findIndex<T>(this T[] array, T item)
{
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < array.Length; i++)
{
if (comparer.Equals(array[i], item)) {
return i;
}
}
return -1;
}
}
Array.IndexOf() gives you the index of an object in an array. Just make sure you use the same data types, i.e. byte here.
This is the full code, tested in .NET 4.5.2
using System;
namespace ConsoleApp2
{
class Program
{
static void Main()
{
byte[] data = { 5, 4, 3, 2, 1 };
Console.WriteLine(Array.IndexOf(data, (byte)2));
Console.ReadLine();
}
}
}
Alternate way is to use Array.FindIndex(array, predicate)
var zeroBasedIndex = Array.FindIndex(data, x => x == (byte)2);
Not sure what you are trying to do but I have fixed your code.
namespace Exmple.Filters
{
public static class DNM
{
public static byte[] Shape(byte[] data)
{
byte[] shape = new byte[data.Length];
byte count = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0)
{
shape[i] = (data[i]);
int index = shape.FindIndex1(count);
int[] a = { 1, 2, 3 };
int index1 = Array.IndexOf(a, (int)3);
count += 1;
}
}
return shape;
}
public static int FindIndex1(this byte[] array, byte item)
{
EqualityComparer<byte> comparer = EqualityComparer<byte>.Default;
for (int i = 0; i < array.Length; i++)
{
if (comparer.Equals(array[i], item))
{
return i;
}
}
return -1;
}
}
}
there were few issues in your code
Naming rule violations
byte[] already has an FindIndex so compiler was getting confused which one to use (I just removed the generic things and changed the name)
array object doesn't have a IndexOf Method, Array class has a method.
this is the problem [enter image description here][1]
class Program
{
/* I 'am sorry, but if written this code in french so I will explain the name of variables in English, and what are they doing
and Yes I am aware this code is spaghetti and I would appreciate if there is a better way to write it
T is an Array, and cible is a target */
public static int [] getRange(int[] T, int cible)
{
// T_indices is an Array of indexes
int[] T_indices = new int[10];
//cpt is a counting variable
int cpt=0;
for (int i = 0; i < T.Length; i++)
{
if(T[i]==cible)
{
for (int j = i; j < T.Length; j++)
{
if(T[i]==T[j])
{
T_indices[cpt] = j;
cpt++;
}
else
{
break;
}
}
break;
}
}
//checking if the element doesn't existe so we can return a -1
if(cpt==0)
{
T_indices = new int[1];
T_indices[0] = -1;
return T_indices;
}
else
{
//T_indices_Finaux is the final index Array
int[] T_indices_Finaux = new int[2];
T_indices_Finaux[0] = T_indices[0];
// Max doesn't need explanation I guess
int max = T_indices[0];
for (int i = 0; i < T_indices.Length; i++)
{
if(max< T_indices[i])
{
max = T_indices[i];
}
}
T_indices_Finaux[1] = max;
if(T_indices_Finaux[0]== T_indices_Finaux[1])
{
T_indices_Finaux = new int[1];
T_indices_Finaux[0] = T_indices[0];
}
return T_indices_Finaux;
}
}
// here we put this spaghetti code to the test suprisenly wroking out
static void Main(string[] args)
{
int[] T = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
for (int i = 0; i < getRange(T, 2).Length; i++)
{
Console.WriteLine(getRange(T, 2)[i]);
}
Console.Read();
}
}
int[] T_indices = new int[10];
How do you know, that 10 is enough? You do not. This magic number would cause, that the code sometimes works and sometimes it just throws out of range exception. Besides this, the code is okay, but you do it in a bit too complicated way. What you need is basically this
public static int[] getRange(int[] T, int cible)
{
for (int i = 0; i < T.Length; ++i)
{
if (T[i] == cible)
{
int j = i + 1;
while (j < T.Length && T[j] == cible) { ++j; }
--j;
if (i == j) { return new int[] { i }; }
return new int[] { i, j };
}
}
return new int[] { -1 };
}
And btw. the test code calls the getRange function up to three times. You should call it once, store the result array and loop over that array.
pleas try this :
change getRange Method to this :
public static List<int> getRange(int[] T, int cible)
{
var result=new List<int>();
var list = T.ToList();
if(!list.Contains(cible))
result.Add(-1);
else
{
result.Add(list.IndexOf(cible));
if (list.Count(x=>x==cible)>1)
result.Add(list.LastIndexOf(cible));
}
return result;
}
and use it like this :
int[] T = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
getRange(T, 2).ForEach(Console.WriteLine);
In this solution you will never get an OutOfRange ٍException and also use the native c # method (for get index of a item in array. "IndexOf" Instead "for") which is much faster and more efficient.
I have a List of Lists consisting of int arrays:
(List<List<int[]>>)
I want to sort the list of lists based on the first index in the int array in the first element of the lists.
My solution so far is:
List<List<int[]>> myList = new List<List<int[]>> { new List<int[]> { new int[] { 1, 5 }, new int[] { 2, 4 } }, new List<int[]> { new int[] { 3, 4 }, new int[] { 0, 1 } } };
myList.OrderByDescending(x => x.Max(y => y[0])).ToList();
In which the result is that the second list comes first and the first would come second.
But I don't like that one as performance is a critical point and I don't like to execute the Max operation as it is useless.
So, is there a better way?
-
EDIT: I finished using:
myList.OrderByDescending(x => x[0][0]).ToList();
As proposed by CodeCaster in the comments. This one was faster in my code than the option proposed by Aldert. But his answer is worth viewing too.
This code is sorting asc or desc depending on the order you pass to the comparer. It runs O*1 over the elements, to setup the structure to be able to compare. I would be interesting to know if it works faster for you (I do think only with very big trees). When you would sort all the inner lists already, you do not need to keep a helper dictionary, you can then take the last element.
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<List<int>> mainList = new List<List<int>>();
List<int> newList = new List<int>();
Random rand = new Random();
for (int i = 0; i < 30; i++)
{
int ra = rand.Next(200);
if (i % 5 == 0)
{
if (newList.Count > 0)
{
newList = new List<int>();
mainList.Add(newList);
}
}
newList.Add(ra);
}
mainList.Sort( new MaxComparer(mainList, false));
foreach (List<int> oneL in mainList)
{
foreach (int oneInt in oneL)
{
Console.Write(oneInt + " ");
}
Console.WriteLine();
}
}
public class MaxComparer : IComparer<List<int>>
{
bool order = false;
Dictionary<int, int> helper = new Dictionary<int, int>();
public MaxComparer(List<List<int>> sortList, bool Order)
{
order = Order;
foreach (List<int> oneL in sortList)
{
int max = int.MinValue;
foreach (int oneInt in oneL)
{
if (max < oneInt) max = oneInt;
}
helper.Add(oneL.GetHashCode(), max);
}
}
public int Compare(List<int> x, List<int> y)
{
return helper[x.GetHashCode()].CompareTo(helper[y.GetHashCode()]) * (order ? 1:-1);
}
}
}
}
This is the answer you are looking for with a binary compare, it is fairly simple because it takes the first element out of the sublint and out of the array (as you where looking for).
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<List<int[]>> mainList = new List<List<int[]>>();
Random rand = new Random();
for (int i = 0; i < 30; i++)
{
List<int[]> subList = new List<int[]>();
int limj = rand.Next(5);
for (int j = 0; j < 5 + limj; j++)
{
int limk = rand.Next(5);
int[] arrayInt = new int[limk + 5];
for (int k = 0; k < limk + 5; k++)
{
arrayInt[k] = rand.Next(200);
}
subList.Add(arrayInt);
}
mainList.Add(subList);
}
mainList.Sort(new MaxComparer(false));
foreach (List<int[]> oneL in mainList)
{
foreach (int[] arrayList in oneL)
{
foreach (int i in arrayList) Console.Write(i + " ");
Console.Write("|");
}
Console.WriteLine();
}
}
public class MaxComparer : IComparer<List<int[]>>
{
bool order = false;
public MaxComparer(bool Order)
{
order = Order;
}
public int Compare(List<int[]> x, List<int[]> y)
{
return x[0][0].CompareTo(y[0][0]) * (order ? 1 : -1);
}
}
}
}
Is this what you are looking for?
var sortedList = myList.OrderBy(x => x.Select(y => y.Select(z => z).OrderBy(z => z))).ToList();
EDIT: I forgot to go one layer deeper. The error was caused because it wanted to order an arrayobject instead of its elements.
My array is below
int[] T1 = new int[]{1,5,4};
int[] T2 = new int[]{2,4,3};
int[] T3 = new int[]{7,9,1};
A result of the sequence I want it is as follows .
int[] result = {7,9,4}
I want to look for a max value same index[(e.g) 1,2,7) in array.
and Merging array is int[] result = {7,9,4}
please let me know best way
thanks
Here is a simple method for performing your desired operation.
int[] result = new int[T1.Length];
for (int i = 0; i < T1.Length; i++)
{
result[i] = new[] {T1[i], T2[i], T3[i]}.Max();
}
You'll have to add using System.Linq in order to enable the Max() extension.
EDIT
Here is a method that allows you to use any number of arrays:
static T[] MaxElements<T>(params T[][] arrays) where T : IComparable<T>
{
return Enumerable.Range(0, arrays[0].Length)
.Select(i => Enumerable.Range(0, arrays.Length)
.Select(a => arrays[a][i]).Max()).ToArray();
}
You'll have to add the using System.Linq; for this one too. You'll have to make sure that all the elements passed in have the same lengths else you will run into an IndexOutOfRangeException.
It can be used as follows;
var result = MaxElements(T1, T2, T3);
Here is what you need:
static void Main(string[] args)
{
GetMaxArray(new[] { 1, 5, 4 }, new[] { 2, 4, 3 }, new[] { 7, 9, 1 });
}
private static void GetMaxArray(params int[][] m)
{
var length = m.First().Length;
var r = new int[length];
for (var i = 0; i < length; i++)
r[i] = m.Select(a => a[i]).Max();
}
public int[] GetMaxValueArray(List<int[]> arrayList)
{
int[] result = null;
int maxArraySize;
int maxCurrentArrayItemValue;
if (arrayList != null && arrayList.Count > 0)
{
maxArraySize = 0;
foreach (int[] array in arrayList)
if (array.Length > maxArraySize)
maxArraySize = array.Length;
result = new int[maxArraySize];
for (int i = 0; i < maxArraySize; i++)
{
maxCurrentArrayItemValue = 0;
foreach (int[] array in arrayList)
if (i < array.Length)
if (array[i] > maxCurrentArrayItemValue)
maxCurrentArrayItemValue = array[i];
result[i] = maxCurrentArrayItemValue;
}
}
return result;
}
I am trying to solve my task using a List and I know I am very close to solving it but I am stuck now. Something is not ok in the code and I can not figure out what it is. Could you please take a look and help:
/*
Write a program that reads an array of integers and removes from it a minimal number of elements in such way that the
remaining array is sorted in increasing order. Print the remaining sorted array.
Example: {6, 1, 4, 3, 0, 3, 6, 4, 5} {1, 3, 3, 4, 5}
*/
using System;
using System.Collections.Generic;
class RemoveMinimalElements
{
static void Main()
{
int n;
n = int.Parse(Console.ReadLine());
List<int> arr = new List<int>();
List<int> sorted = new List<int>();
int maxSubsetLenght = 0;
for (int i = 0; i < n; i++)
{
arr.Add(int.Parse(Console.ReadLine()));
}
for (int i = 1; i <= (int)Math.Pow(2, n) - 1; i++)
{
int tempSubsetLenght = 0;
string tempString = "";
List<int> temp = new List<int>();
for (int j = 1; j <= n; j++)
{
int andMask = i & (1 << j);
int bit = andMask >> j;
if (bit == 1)
{
temp.Add(arr[n - 1 - j]);
tempSubsetLenght++;
}
if (tempSubsetLenght > maxSubsetLenght)
{
maxSubsetLenght = tempSubsetLenght;
for(int k =1; k < temp.Count; k ++)
{
if (temp[k] >= temp[k - 1])
{
sorted = temp;
}
}
}
}
}
for (int i = sorted.Count - 1; i > 0; i--)
{
Console.WriteLine(sorted[i]);
}
}
}
I didn't follow the code, I just tested your app.
This is my first input: 5.
Then I entered these 5 inputs 2,4,6,8,10 so
arr = {2,4,6,8,10};
And when it came to the last lines it gave me the ArguementOutOfRangeException (Index was out of range. Must be non-negative and less than the size of the collection.) because it was trying to fetch arr[item] and item is 6 so it's trying to fetch arr[6] which does not exist.
I don't know if an exhaustive search is suitable for your case, but will this work for you?
static void Main(string[] args)
{
int[] input = new[] { 6, 1, 4, 3, 0, 3, 6, 4, 5 };
int[] expectedOutput = new[] { 1, 3, 3, 4, 5 };
int[] solution = TryGetSolution(input);
Console.WriteLine("Input: " + FormatNumbers(input));
Console.WriteLine("Expected Output: " + FormatNumbers(expectedOutput));
Console.WriteLine("Output: " + FormatNumbers(solution));
Console.ReadLine();
}
private static string FormatNumbers(int[] numbers)
{
return string.Join(", ", numbers);
}
private static int[] TryGetSolution(int[] input)
{
return TryWithoutAnyItem(input);
}
private static int[] TryWithoutAnyItem(int[] items)
{
return Enumerable.Range(0, items.Length)
.Select(i => TryWithoutItem(items, i))
.Where(solution => solution != null)
.OrderByDescending(solution => solution.Length)
.FirstOrDefault();
}
private static int[] TryWithoutItem(int[] items, int withoutIndex)
{
if (IsSorted(items)) return items;
var removed = items.Take(withoutIndex).Concat(items.Skip(withoutIndex + 1));
return TryWithoutAnyItem(removed.ToArray());
}
private static bool IsSorted(IEnumerable<int> items)
{
return items.Zip(items.Skip(1), (a, b) => a.CompareTo(b)).All(c => c <= 0);
}
}
I solved it! Thank you very much for your support. I am a beginer and I am not able to use and understand more difficult stuff yet so here is what I did whit the things I already know:
/*
Write a program that reads an array of integers and removes from it a minimal number of elements in such way that the
remaining array is sorted in increasing order. Print the remaining sorted array.
Example: {6, 1, 4, 3, 0, 3, 6, 4, 5} {1, 3, 3, 4, 5}
*/
using System;
using System.Collections.Generic;
class RemoveMinimalElements
{
static bool CheckAscending(List<int> list)
{
bool ascending = true;
for (int i = 0; i < list.Count - 1; i++)
{
if (list[i] > list[i + 1])
{
ascending = false;
}
}
return ascending;
}
static void Main()
{
int n;
n = int.Parse(Console.ReadLine());
List<int> arr = new List<int>();
List<int> sorted = new List<int>();
int maxSubsetLenght = 0;
for (int i = 0; i < n; i++)
{
arr.Add(int.Parse(Console.ReadLine()));
}
for (int i = 1; i <= (int)Math.Pow(2, n) - 1; i++)
{
int tempSubsetLenght = 0;
List<int> temp = new List<int>();
for (int j = 1; j <= n; j++)
{
if (((i >> (j - 1)) & 1) == 1)
{
temp.Add(arr[j - 1]);
tempSubsetLenght++;
}
}
if ((tempSubsetLenght > maxSubsetLenght) && (CheckAscending(temp)))
{
sorted = temp;
maxSubsetLenght = tempSubsetLenght;
}
}
for (int i = 0; i < sorted.Count; i++)
{
Console.WriteLine(sorted[i]);
}
}
}
This works for me
private static void FindLongestRisingSequence(int[] inputArray)
{
int[] array = inputArray;
List<int> list = new List<int>();
List<int> longestList = new List<int>();
int highestCount = 1;
for (int i = 0; i < array.Length; i++)
{
list.Add(array[i]);
for (int j = i+1; j < array.Length; j++)
{
if (array[i] < array[j])
{
list.Add(array[j]);
i++;
}
else
{
break;
}
i = j;
}
// Compare with in previous lists
if (highestCount < list.Count)
{
highestCount = list.Count;
longestList = new List<int>(list);
}
list.Clear();
}
Console.WriteLine();
// Print list
Console.WriteLine("The longest subsequence");
foreach (int iterator in longestList)
{
Console.Write(iterator + " ");
}
Console.WriteLine();
}