Страница 1 из 2

Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 13:00
maksimov
Суть следующая.
Есть массив.
int size = 10;
byte[] data = new byte[size];

Необходимо зациклить его пространство индексов. То есть, что бы по индексу 10 мы получали элемент с индексом 0, 11 -> 1, -4 -> 6, -12 -> 8,...

Самый очевидный тут вариант, конечно же проверка условием:
Синтаксис:
Используется csharp
byte GetElem(int x)
 {
            while (x > size - 1)
                x = x - size;

            while (x < 0)
                x = x + size;
return data[x];
}
 

Но возможно, есть и какой-то другой, более оптимальный (с точки зрения производительности) вариант?

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

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 13:06
Cr0c
Mathf.Repeat

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 13:11
snezhok_13
Остаток от деления вам нужен. В C# это %

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 13:32
maksimov
snezhok_13 писал(а):Остаток от деления вам нужен. В C# это %

Остаток от деления никак не поможет мне с отрицательными индексами.

Кроме того, арифметическое решение в данном случае смущает меня ещё тем, что "выход за область индексации" происходит не всегда. А деление в таком случае придётся производить при любом обращении к элементу. Насколько получение остатка от деления, легче/тяжелее операции сравнения?


* * *
У меня появилась было мысль, попробовать переопределить array, что бы задействовать IndexOutOfRangeException...
Но вот как это реализовать на практике - чё та не докумекиваю.

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 14:50
Woolf
-4 -> 6

Откуда такая извращенная логика? Почему 6, а не 4?


Остаток от деления никак не поможет мне с отрицательными индексами.

if (index<0) { ....

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 15:03
Cr0c
Woolf писал(а):
-4 -> 6

Откуда такая извращенная логика? Почему 6, а не 4?


Остаток от деления никак не поможет мне с отрицательными индексами.

if (index<0) { ....

Можно без ветвления
Синтаксис:
Используется csharp
while (index>=array.Length) index -= array.Length;
while (index<0) index += array.Length;
 

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 15:32
Woolf
Вы считаете, что цикл быстрее одного if и одного деления с остатком?

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 15:35
Cr0c
Woolf писал(а):Вы считаете, что цикл быстрее одного if и одного деления с остатком?

Нет, но в качестве примера, что можно решить более чем одним-двумя способами ))

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 15:43
maksimov
Woolf писал(а):
-4 -> 6

Откуда такая извращенная логика? Почему 6, а не 4?

Это не логика, а математика. =)
Индексу просто идут по кругу. Шаг вперёд из точки 9 переносит нас в точку 0, а шаг назад из точки 0 переносит нас в точку 9. Соответственно, четыре шага назад из точки 0, переносят нас в точку 6.

Как верно было замечено в фильме Snatch: "Когда ты двигаешься назад, вещи двигаются на тебя со спины!" )))

Woolf писал(а):
Остаток от деления никак не поможет мне с отрицательными индексами.

if (index<0) { ....

И... ?

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 15:46
maksimov
Cr0c писал(а):
Синтаксис:
Используется csharp
while (index>=array.Length) index -= array.Length;
while (index<0) index += array.Length;
 

Это дословный реплэй того, что я написал в изначальном посте. ))

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 17:35
Woolf
И... ?

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

Пример:

Синтаксис:
Используется csharp
int cindex=(indx>0)? indx%lng:lng-1-Matf.Abs(indx)%lng;
 


Длина массива lng=10, входящий индекс indx=22, результат 2
Длина массива lng=10, ваш индекс indx=-22, результат 7

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 19:04
maksimov
Woolf писал(а):Длина массива lng=10, ваш индекс indx=-22, результат 7

Результат должен быть 8.

Для отрицательных значений ваше выражение даёт неверный результат.

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 20:29
Woolf
maksimov писал(а):
Woolf писал(а):Длина массива lng=10, ваш индекс indx=-22, результат 7

Результат должен быть 8.

Для отрицательных значений ваше выражение даёт неверный результат.


Каким образом он должен быть восемь, если надо отступить 2 элемента от последнего индекса массива?
Вы же сами писали, -1 - отступить на один элемент от края массива, т.е. получим 8, -2 - два элемента, получим -7. Массив же от нуля считается, вы не забыли, что при длине массива 10, у вас последний индекс 9?

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 21:03
maksimov
Woolf писал(а):Вы же сами писали, -1 - отступить на один элемент от края массива, т.е. получим 8, -2 - два элемента, получим -7. Массив же от нуля считается, вы не забыли, что при длине массива 10, у вас последний индекс 9?

Совершенно верно - последний индекс у нас 9 (а первый - 0).
И именно поэтому, если мы сделаем шаг назад, то с первого элемента массива (0) попадаем на последний (9)

2: 2, 1 : 1, 0 : 0, -1 : 9, -2 : 8, -3 : 7, -4 : 6, -5 : 5, -6 : 4, -7 : 3, -8 : 2, -9 : 1, -10 : 0, -11 : 9, -12 : 8, -13 : 7, -14 : 6, -15 : 5, -16 : 4, -17 : 3, -18 : 2, -19 : 1, -20 : 0, -21 : 9, -22 : 8

Re: Оптимальный вариант зацикливания индексов массива

СообщениеДобавлено: 06 фев 2018, 22:16
Woolf
maksimov писал(а):
Woolf писал(а):Вы же сами писали, -1 - отступить на один элемент от края массива, т.е. получим 8, -2 - два элемента, получим -7. Массив же от нуля считается, вы не забыли, что при длине массива 10, у вас последний индекс 9?

Совершенно верно - последний индекс у нас 9 (а первый - 0).
И именно поэтому, если мы сделаем шаг назад, то с первого элемента массива (0) попадаем на последний (9)

2: 2, 1 : 1, 0 : 0, -1 : 9, -2 : 8, -3 : 7, -4 : 6, -5 : 5, -6 : 4, -7 : 3, -8 : 2, -9 : 1, -10 : 0, -11 : 9, -12 : 8, -13 : 7, -14 : 6, -15 : 5, -16 : 4, -17 : 3, -18 : 2, -19 : 1, -20 : 0, -21 : 9, -22 : 8


Ну так допишите, как вам надо. Я идею дал, а напильником уже и сами допилите.