List подсчёт чисел c#
У меня есть List (ниже код)
List<KeyLenght> lenght = new List<KeyLenght>(); //лист с ключами
#region подсчёт
lenght.Add(new KeyLenght() { lenght = 2, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 3, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 4, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 5, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 6, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 7, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 8, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 9, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 10, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 11, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 12, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 13, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 14, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 15, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 16, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 17, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 18, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 19, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 20, howMany = 0 });
lenght.Add(new KeyLenght() { lenght = 21, howMany = 0 });
#endregion
(после main есть ещё класс для этого листа)
public class KeyLenght
{
public int lenght;
public int howMany;
}
Я в цикле считаю числа, которые "работают" по определённой формуле. Далее, мне нужно найти число, которое чаще всего встречается.
Пытался реализовать вот так:
for (double l = 2; l <= 21; l++)
{
if ((j - i) > 0) //если число положительное (проверка)
{
double Check = (j - i) / l; //и выполняется условие
if (Check % 1 == 0) //и остаток от деления равен 0
{
lenght[Convert.ToInt32(l)].howMany++; //ТО увеличить howMany на 1
}
}
}
Но почему-то это не работает - выдаёт ошибку: System.ArgumentOutOfRangeException: "Индекс за пределами диапазона. Индекс должен быть положительным числом, а его размер не должен превышать размер коллекции. Имя параметра: index"
Ответы (1 шт):
Во первых, для ваших целей лучше подойдёт Dictionary, а во вторых... Индексирование lenght[] имеет по индексу 0 объект:
lenght.Add(new KeyLenght() { lenght = 2, howMany = 0 });
А значит объект
lenght.Add(new KeyLenght() { lenght = 21, howMany = 0 });
будет расположен в списке по индексу 19, а вы пытаетесь обратится к нему по lenght[21].
Так что в конкретном случае делайте так:
lenght[Convert.ToInt32(l)-2].howMany++;
Правильным решением будет использовать словарь для этих целей, и класс KeyLenght будет не нужен:
Dictionary<int, int> KeyLength = new Dictionary<int, int>();
for (double l = 2; l <= 21; l++)
{
if ((j - i) > 0) //если число положительное (проверка)
{
double Check = (j - i) / l; //и выполняется условие
if (Check % 1 == 0) //и остаток от деления равен 0
{
int l_int = Convert.ToInt32(l);
if (KeyLength.ContainsKey(l_int)) KeyLength[l_int]++;
else KeyLength[l_int] = 1;
}
}
}
Чтобы получить наиболее чаще встречающийся элемент:
if (dic.Count = 0) return -1; //элементов нет вообще
int maxval = dic.Max(m => m.Value); //наибольшее значение счётчика
IEnumerable<KeyValuePair<int, int>> listwithmaxvals = dic.Where(w => w.Value == maxval); //список записей с наибольшим значением счётчика
int[] maxvalkeys = listwithmaxvals.Select(s => s.Key).ToArray(); //массив ключей с наибольшим значением счётчика
int maxvalkey = listwithmaxvals.ElementAt(0).Key; //первый элемент с максимальным значением счётчика
int maxvalfirstval = dic[maxvalkey]; //значение первого элемента, смысла особо не имеет, т.к. есть int maxval