TheCeleryK Ответов: 5

Отображать каждое 10-е число в массиве?


У меня есть код, который сортирует массив в порядке возрастания, я пытаюсь отобразить каждое 10-е число из этого массива. Однако я продолжаю получать ошибку:
System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

Может ли кто-нибудь объяснить, почему он появляется и как я могу его исправить?
Спасибо

Что я уже пробовал:

Ошибка появляется по адресу:
Console.Write(arr[i * 10] + " ");


код:
{
                string[] text = File.ReadAllLines("Net_1_256\\Net_1_256.txt");
                List<int> values = new List<int>(text.Length);
                int i;
                foreach (string line in text)
                    {
                    int value;
                    if (int.TryParse(line,out value))
                        {
                            values.Add(value);
                        }
                }

                int[] arr = values.ToArray();
                for (i = 0; i < arr.Length; ++i)
                HeapSort(arr, arr.Length);

                Console.Write("\nSorted Array is: ");
                for (i = 0; i < arr.Length; ++i)
                {
                    Console.Write(arr[i * 10] + " ");
                }
            }

Benktesh Sharma

Вы намеревались напечатать каждый 10 - й, включая первый или исключая первый?

5 Ответов

Рейтинг:
39

Richard Deeming

Подумайте об этом - ваша переменная i будет проходить через каждый допустимый индекс в массиве, так что i * 10 большую часть времени это будет недопустимый индекс.

Если допустимые показатели 0 к 4, вы пытаетесь отобразить элементы в 0, 10, 20, 30, и 40 Только первый из них будет успешным .

Чтобы отобразить каждый 10-й элемент в массиве, измените свой цикл на инкремент на 10 вместо 1:

for (i = 0; i < arr.Length; i += 10)
{
    Console.Write(arr[i] + " ");
}

NB: Согласно дискуссия в гостиной[^], потенциально существует некоторая путаница в ваших требованиях. Код в вашем вопросе предполагает, что вы хотите начать с первого элемента массива. Но "каждый 10-й элемент" это может быть истолковано как означающее, что вы начинаете с десятого элемента массива.

Если вы хотите начать с 10-го элемента в массиве, то вам просто нужно изменить начальную позицию цикла:
for (i = 9; i < arr.Length; i += 10)


Maciej Los

Вверх-проголосовали!

Рейтинг:
29

Benktesh Sharma

Когда вы пишете 10-й элемент, число может быть вне диапазона. Например, если у вас есть 2 элемента в массиве, вы пытаетесь получить доступ к элементу в 2 * 10, который не существует. Вы можете решить эту проблему, либо поместив условие в цикл for, где i * 10 < arr.Length (пример показан). Другой способ-это i < arr.Length/10 (так что i*10 всегда находится в пределах границы). Приведенный ниже код предполагает, что требование состоит в том, чтобы первый элемент и каждый 10-й после первого были напечатаны.

{
                string[] text = File.ReadAllLines("Net_1_256\\Net_1_256.txt");
                List<int> values = new List<int>(text.Length);
                int i;
                foreach (string line in text)
                    {
                    int value;
                    if (int.TryParse(line,out value))
                        {
                            values.Add(value);
                        }
                }

                int[] arr = values.ToArray();
                for (i = 0; i < arr.Length; ++i)
                HeapSort(arr, arr.Length);

                Console.Write("\nSorted Array is: ");
                for (i = 0; i < arr.Length && i*10 < arr.Length; ++i)
                {
                    Console.Write(arr[i * 10] + " ");
                }
            }


Nelek

Это печатает элемент [0], и это не 10-й элемент. Дополнительное если необходимо в последнем для

Benktesh Sharma

@Nelek, цикл печатает фактическое число в массиве. Оригинальный код с плаката вопроса предназначался для печати 1-го, 10-го и так далее. Кроме того, "каждый десятый" подразумевает первый, десятый, двадцатый и так далее. Возможно, вы правы в обработке других граничных условий, но первоначальная проблема заключалась в том, что "индекс вне связанного исключения".

Nelek

Ладно... это, наверное, языковая проблема.
Для меня каждый 10-й не обязательно означает первый. Я бы так и сделал [9], [19],... (кардиналы 10, 20, 30...) и так далее вместо [0], [10] (кардиналы 1, 11, 21,...)

Benktesh Sharma

Я вижу. Спасибо.

Rick York

Это решение неверно. Когда i равно 0, он печатает элемент 0, и это не десятый элемент. Это нулевой элемент, если это вообще слово.

Benktesh Sharma

Решение является правильным в той мере, в какой это предположение повторяется. Сначала и каждый 10-й после этого. Обновленный.

Rick York

Вопрос не требовал, чтобы первый пункт был напечатан.

Benktesh Sharma

Вопрос заключается только в том, чтобы указать проблему в индексе вне связанной ошибки. Исходный код предназначался для отображения первым и каждого 10-го после него, как и предлагаемое решение.

Рейтинг:
1

Patrice T

Цитата:
Однако я продолжаю получать ошибку

Это не прямое решение, но отладчик-это инструмент, который поможет вам понять, что происходит в вашем коде.
-----
Ваш код ведет себя не так, как вы ожидаете, или вы не понимаете, почему !

Существует почти универсальное решение: запускайте свой код на отладчике шаг за шагом, проверяйте переменные.
Отладчик здесь, чтобы показать вам, что делает ваш код, и ваша задача-сравнить с тем, что он должен делать.
В отладчике нет никакой магии, он не знает, что должен делать ваш код, он не находит ошибок, он просто помогает вам, показывая, что происходит. Когда код не делает того, что ожидается, вы близки к ошибке.
Чтобы увидеть, что делает ваш код: просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик - Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010 - YouTube[^]

Отладка кода C# в Visual Studio - YouTube[^]

Отладчик здесь только для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.


0x01AA

"Это не прямое решение", это даже не косвенное решение. Извините меня, но такая штука выглядит как охота на рептилий.
Кстати, никакого голосования с моей стороны

Patrice T

Привет, спасибо за комментарий.
Во - первых, я не хотел просто повторять то, что было сказано в предыдущем решении 3.
Мой опыт, датируемый еще до интернета, заключается в том, что отладчик всегда очень помогает понять, что мой код делает неправильно.
К сожалению, похоже, что отладчик сегодня не в большой моде и что новички часто учатся кодировать, не обучаясь отладчику.

Рейтинг:
1

Rick York

Десятый элемент в массиве-это элемент 9, так как первый элемент-это элемент 0. Каждый десятый элемент-это пункты 9, 19, 29, 39 и т.д. Вы могли бы попробовать что-то вроде этого :

for( index = 9; index < arr.length; index += 10 )
{
    Console.Write( arr[index] + " " );
}
Если массив содержит менее 10 элементов, то ничего не будет напечатано, да и не должно быть.


Richard Deeming

Итак, вы проголосовали против моего решения, пока я спал, потому что дискуссия в гостиной, в которой вы даже не участвовали, решила, что "каждый 10-й пункт" это означало начать с другого индекса.

Затем выложил то, что по сути является копией кода из моего решения (с измененным именем переменной, чтобы она не компилировалась, если ОП попытается ее использовать), изменяя начало цикла.

Не круто. 👎

Stefan_Lang

Это может быть проблемой языка, но когда вы говорите "пункт 9", я понимаю " элемент arr[8]". В моем понимании нет такого понятия, как "элемент 0": Первый элемент в наборе всегда является элементом 1.

Я не уверен, что носитель английского языка поймет это по-другому.

Rick York

Не круто??? То, что я написал, было написано до вашей правки.

Rick York

Когда я писал пункт 9, я имел в виду arr[9].

Richard Deeming

Перечитайте мой комментарий.

Обратите внимание, что я сказал: "... по существу копия ..." Блок кода слишком тривиален, чтобы предполагать, что вы на самом деле скопировать его. Я просто указывал на сходство. Если бы вы не переименовали переменную, ваш код был бы одним изменением символа от моего.

Мое решение было опубликовано задолго до вашего. Вы, очевидно, видели его, потому что прокомментировали его - с тех пор вы удалили этот комментарий, но удаленные комментарии все еще видны.

Голосовать против моего решения, потому что я не редактировал его, чтобы учесть дискуссию, которая произошла, пока я спал, определенно "не круто".

Рейтинг:
0

V.

если i * 10 > arr.Length чем вы получите эту ошибку.

Эмпирическое правило заключается в том, чтобы немного не манипулировать своим индексом внутри цикла:
так


for (i = 0; i < arr.Length; i++)
{
    //here you actually manipulate the index
    Console.Write(arr[i*10] + " ");
}

это не такая уж хорошая идея.

чтобы избежать ошибок в будущем можно добавить чек
if(i * 10 < arr.Length) { /*do something here*/ }

или еще лучше, переосмыслите свою петлю :
например, добавить if(i%10 == 0){ /*write out what you need*/ }

надеюсь, это поможет.
Хотя это должно быть в ваших учебниках или решаться с вашими одноклассниками...


Nelek

Ваше или лучше "если" напечатало бы самое первое число массива (Pos[0]), и оно не входит в требование.
Если вы хотите сделать это таким образом, вам потребуется дополнительное предложение if:
if((i%10 == 0)&&(i!=0)){ /*write out what you need*/ }

и это будет работать лучше, если цикл просто использует i++ вместо i+=10, как вы написали

Richard Deeming

Незначительная поправка: вы получите ошибку, если i * 10 >= arr.Length. :)

V.

это был тип-о ;-)
Исправленный

Rick York

Это решение неверно. Когда i равно 0, он печатает элемент 0, и это не десятый элемент.

PIEBALDconsult

Тем не менее, это может быть то, что имел в виду ОП, но было неясно, как он это описал.