Возникли проблемы при обращении массива

0

Вот мой код:

#include <iostream>

using namespace std;

void reverse(int *, int);

int main()
{
    const int len = 10;
    int intArray[len] = {5, 6, 4, 1, 3, 10, 15, 13, 2, 7};
    reverse(intArray, len);
}

void reverse(int intArray[], int len)
{
    int j = len;
    for(int i = 0; i < len; i++)
    {
        --j;
        intArray[i] = intArray[j];
        cout << intArray[i] << " ";

    }
}

Тогда вот мой вывод:

7 2 13 15 10 10 15 13 2 7

Я вижу некоторые примеры кода, делающего то же самое, и я хочу знать, почему все они используют временную переменную, и если это необходимо?

Кроме того, этот вопрос является вариацией задания MIT OCW. Хотя их назначение не требует отпечатка обратного массива, они хотят, чтобы мы сохранили обратные значения в исходном массиве. Но почему-то их цикл for работает только на половину длины? Вот их решение:

void reverse (int numbers [] , const int numbersLen ) 
{

for(int i = 0; i < numbersLen / 2; ++ i ) {

int tmp = numbers [ i ];

int indexFromEnd = numbersLen - i - 1;

numbers [ i ] = numbers [ indexFromEnd ];

numbers [ indexFromEnd ] = tmp ;

}

}
  • 0
    Сначала попробуйте изменить условие цикла на i < len / 2 и посмотрите, что произойдет.
  • 0
    Я получаю это: 7 2 13 15 10, что правильно, но я уже знаю, что из моего начального вывода: только половина моего вывода верна.
Показать ещё 2 комментария
Теги:
arrays
algorithm
reverse

4 ответа

1
Лучший ответ

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

Если вам нужно использовать тот же массив, вы должны поменять соответствующие элементы. Для подкачки вам нужна временная переменная и запустите цикл только в половине длины массива.

2

Просто используйте стандартный алгоритм std::reverse с помощью итераторов std::begin и std::end

#include <algorithm>
#include <iostream>

int main()
{
    const int len = 10;
    int intArray[len] = {5, 6, 4, 1, 3, 10, 15, 13, 2, 7};
    std::reverse(std::begin(intArray), std::end(intArray));

    for (auto&& e : intArray)
        std::cout << e << ", ";
}

Живой пример.

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

template<class BidirIt>
void reverse(BidirIt first, BidirIt last)
{
    while ((first != last) && (first != --last)) {
        std::iter_swap(first++, last);
    }
}

Здесь std::iter_swap(a, b) просто вызывает std::swap(*a, *b). Конечно, вы можете придумать свой своп.

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

  • 2
    Это, очевидно, домашнее задание, в котором смысл состоит в том, чтобы реализовать алгоритм разворота, используя тип std::reverse пропускающий точку ...
  • 0
    @MatteoItalia один из пунктов - попытаться написать алгоритмы в стиле STL
1

Используйте следующий цикл для обратной функции:

int tmp;
for (int i = 0; i < len / 2; i++)
{
    --j;
    tmp = intArray[j];
    intArray[j] = intArray[i];
    intArray[i] = tmp;
}

затем напечатайте массив из другого цикла.

0

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

void reverse(int intArray[], int len)
{
    if (len <= 0)
        return;
    cout << intArray[len - 1] << " ";
    if (len == 1)
        return;
    reverse(intArray + 1, len - 2);
    int tmp = intArray[0];
    cout << tmp << " ";
    intArray[0] = intArray[len - 1];
    intArray[len - 1] = tmp;
}

Переменная tmp необходима для замены двух значений. В противном случае при первом присваивании (=) вы потеряете некоторые данные.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню