Задача на обход массива

MacSeem

Пользователь
Пользователь
Май 15, 2020
37
6
8
Придумал сам себе задачу.
Есть лист c числовыми значениями, допустим s = [4, 0, 2, 1, 3]
Условие такое - начинаем обход с нулевой ячейки и находим там значение 2, значит следом идем в ячейку 2 и находим там 0. Зациклились. Обходим сдвигом на единицу вправо. Если и там уже были - сдвигаемся ещё на одну ячейку.

Вопроса два. Почему он в самом конце прогоняет проверку (видно по тому, что он печатает oops)? По идее же всё должно закончиться выводом последнего элемента массива.
И основной. Это задача учебная, поэтому производительность не важна, но если представить рабочую задачу, где элементов, скажем, сто тысяч, то наверное негоже гонять циклом в каждом проходе проверку, это же не лучший способ? Есть какие-то более правильные варианты решения подобных задач?

Python:
c = 0
lst = []
for i in range(5):
    lst.append(c)
    x = s[c]    
    print ('place', c, 'value', x)
    c = x
    for e in range(len(lst)):
        if c in lst:
            print ('oops') # чтобы видеть, когда мы натыкаемся на уже обработанную ячейку
            c+=1

Результат исполнения:
Код:
place 0 value 4
place 4 value 3
place 3 value 1
place 1 value 0
oops
oops
place 2 value 2
oops
oops
oops
 
Последнее редактирование:

veDO

Новичок
Пользователь
Май 15, 2020
12
4
3
Python:
s = [3, 0, 2, 5, 4, 1]
c = 0
lst = []
for i in range(len(s)):
    x = s[c]
    while c in lst:
        #print ('oops') чтобы видеть, когда мы натыкаемся на уже обработанную ячейку
        c += 1
        if len(lst) < len(s):
            x = s[c]
        elif len(lst) >= len(s):
            c = -1
    lst.append(c)
    print ('place', c, 'value', x)
    c = x
Немного переделал вашу программу, теперь работает с любой длинной списка и выдает правильные числа.
Вот выход:
place 0 value 3
place 3 value 5
place 5 value 1
place 1 value 0
place 2 value 2
place 4 value 4
У вас все замораживалось из-за того, что все числа из списка программа уже перебрала, а повтор вы запретили.
 
  • Мне нравится
Реакции: Vlad_SD и MacSeem

MacSeem

Пользователь
Пользователь
Май 15, 2020
37
6
8
Спасибо. Хорошо у вас то, что в цикл на обработку программа уходит только тогда, когда наткнулась на уже обработанную ячейку. У меня тупо всё проверялось, это явно лишнее.

//У вас все замораживалось из-за того, что все числа из списка программа уже перебрала, а повтор вы запретили
Вот это не очень понял, можно подробнее?

И вот этот блок не совсем понятно зачем, и без него работает же. Цикл for по изначальному условию не повторится больше раз, чем число элементов массива.

Python:
        if len(lst) < len(s):
            x = s[c]
        elif len(lst) >= len(s):
            c = -1
 

veDO

Новичок
Пользователь
Май 15, 2020
12
4
3
Спасибо. Хорошо у вас то, что в цикл на обработку программа уходит только тогда, когда наткнулась на уже обработанную ячейку. У меня тупо всё проверялось, это явно лишнее.

//У вас все замораживалось из-за того, что все числа из списка программа уже перебрала, а повтор вы запретили
Вот это не очень понял, можно подробнее?

И вот этот блок не совсем понятно зачем, и без него работает же. Цикл for по изначальному условию не повторится больше раз, чем число элементов массива.

Python:
        if len(lst) < len(s):
            x = s[c]
        elif len(lst) >= len(s):
            c = -1
У вас все замораживалось из-за того, что все числа из списка программа уже перебрала, а повтор вы запретили
В вашем коде каждый индекс добавлялся в список lst. Вот ваш вывод.
place 0 value 4
place 4 value 3
place 3 value 1
place 1 value 0
oops
oops
place 2 value 2
oops
oops
oops
Все варианты place уже перебрались, поэтому дальше идет проверка 'oops', ведь если значение place уже в списке lst, к этому значению прибавляется 1.

И вот этот блок не совсем понятно зачем, и без него работает же. Цикл for по изначальному условию не повторится больше раз, чем число элементов массива.
Объясняю. Я оформил все через цикл фор, чтобы на выходе мне выдавалось ровно столько значений, сколько элементов в списке. Внутри цикла for я спрятал цикл while, который перебирает все значения c в диапазоне от 0 - количества элементов списка lst. Если мы начинаем цикл While со значением с = 3, а дальше уже все занято и нам нужно что бы выдался вариант, где c = 2, то без этого элемента цикл просто дойдет до c = len(s) и крашнется, ведь элемента с индексом > len(s) нет. А это условие проверяет и если с = len(s), то обнуляет c и перебирает индексы до изначального значения c. А если уже выдалось необходимое количество элементов, то цикл for просто не начинается заново. Надеюсь что объяснил понятно, так как я не мастер этого дела.
 
  • Мне нравится
Реакции: MacSeem и Vlad_SD

Форум IT Специалистов