Как решить проблему индекса вне границ, когда нужно учитывать обоих соседей элемента массива? - PullRequest
0 голосов
/ 11 октября 2018

Эта вещь, которую я пишу, должна делать следующее: получить в качестве входных данных затем число имен многих детей и столько оценок.Затем назначьте каждому ребенку количество монет, чтобы, если его класс был больше, чем у его соседа, он получал больше монет, и наоборот.Я написал следующее:

        string input = Console.ReadLine();
        int n = Convert.ToInt32(input);
        int i = 0;
        string[] names = new string[n];
        for (i = 0; i < n; i++)
        {
            names[i] = Console.ReadLine();
        }
        string[] gradeText = new string[n];
        int[] grades = new int[n];

        for (i = 0; i < n; i++)
        {
            gradeText[i] = Console.ReadLine();
            grades[i] = Convert.ToInt32(gradeText[i]);
        }

        int[] minCoins = { 1, 2, 3 };
        int[] coinArray = new int[n];
        for (i = 1; i < n - 2; i++)
        {
            if (grades[0] > grades[1])
            {
                coinArray[0] = 3;
            }

            else
            {
                coinArray[0] = 1;
            }
            if (grades[i] > grades[i + 1] && grades[i] > grades[i - 1])
            {
                coinArray[i] = 3;
            }
            if (grades[i] > grades[i + 1] || grades[i] > grades[i - 1])
            {
                coinArray[i] = 2;
            }
            if (grades[i] < grades[i + 1] && grades[i] < grades[i - 1])
            {
                coinArray[i] = 1;
            }

            if (grades[n - 1] > grades[n - 2])
            {
                coinArray[n - 1] = 3;
            }
            else
            { coinArray[n - 1] = 1; }

        }



        for (i = 0; i < n; i++)
        {
            Console.WriteLine(names[i] + " " + coinArray[i]);
        }

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

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Другие здесь уже предложили, как бороться с проблемами индексации за пределами границ.Так что это немного другой подход к решению вашей проблемы.

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

Ваш цикл for пытается сделать довольно много.Каждая итерация может иметь много проверок.Кроме того, вы делаете проверки, которые вы сделали ранее.

  1. У меня есть сосед слева.
  2. У меня есть сосед справа.
  3. Получил ли я лучшую оценку, чем оба соседа.
  4. Получил ли я лучшую оценку, чем один сосед.
  5. Я проиграл обоим соседям.

Мой совет - разбить это на две отдельные задачи.

1, чтобы подсчитать, сколько соседей каждый человек получил выше, чем оценка.

string[] names = new string[]{"John", "Paul", "Ringo", "George"};
int[] grades = new[] {3, 4, 3,2};
int[] winnersandloser = new int[4];
for (int i = 1; i < grades.Length; i++) //note starting at position 1 so I dont need to handle index out of bounds inside the for loop
{
    if (grades[i] > grades[i - 1])
    {
        winnersandloser[i]++;
    }
    else
    {
        winnersandloser[i - 1]++;
    }
}

В приведенном выше коде у вас должен быть массив со следующими значениями: {0,2,1,0}

0 = вы проиграли обоим соседям 1 = вы победили одного соседа2 = молодец, вы победили обоих соседей

Затем с помощью этого массива winnersandlosers вы можете рассчитать, сколько монет дать каждому человеку.Я оставлю это для вас.

Обновление

Если вам требуется другое поведение для первого и последнего в списке людей, вам нужно добавить логику в свой код для распределения монет,

Массив дает каждое значение и значение индекса, начиная с 0. Таким образом, 0 указывает на первое значение в вашем массиве.Джордж является 4-й записью в массиве, но так как индекс массива начинается с 0, значение индекса равно 3, вы также получаете это от arrayname.Length - 1

Так что теперь, когда вы перебираете массив для выделения монет, мы можемдобавить проверку для первой и последней позиции в массиве.

//allocating coins
for (int i = 0; i < winnersandloser.Length;  i++)
{
    if (i == 0 || i == winnersandloser.Length - 1)
    {
        //allocating rules for first and last 
    }
    else
    {
        //allocating rules for everyone else
    }
}
0 голосов
/ 11 октября 2018

Один из распространенных способов решения этой проблемы - увеличение размера массива на столько элементов, сколько вам нужно, чтобы смотреть вперед или назад.Поместите свои реальные элементы в «середину» 1 этого массива и подходящие фиктивные значения в элементы в начале / конце, которые не соответствуют реальным элементам.Вы выбираете фиктивные значения так, чтобы сравнения работали так, как вам нужно (например, часто вы помещаете int.MinValue в фиктивные элементы в начале и int.MaxValue в фиктивные элементы в конце).

Затем вы просто перечисляете действительные элементы в массиве, но все ваши вычисленные значения просмотра вперед / назад по-прежнему соответствуют действительным индексам в массиве.


1 Иногда выбудет неровно смотреть в будущее / смотреть за требованиями, так что это может быть не настоящая середина.Например, вам нужно иметь возможность смотреть за одним элементом и опережать 3 элемента, и вы хотите обработать 20 элементов.Затем вы создаете массив, содержащий 24 записи, помещаете фиктивные значения в индексы 0, 21, 22 и 23 и заполняете ваши реальные элементы в индексы 1 - 20.

...