Это возможно написать это, используя один цикл, но я настоятельно рекомендую не делать этого.Двойной цикл for - это хорошо зарекомендовавший себя термин, который программисты умеют читать, и если вы объединяете два цикла в один, вы жертвуете удобочитаемостью.Более того, неясно, будет ли это на самом деле ускорять выполнение кода, поскольку компилятор уже очень хорошо оптимизирует циклы.Объединение двух циклов в один требует дополнительной математики на каждом шаге, которая почти наверняка медленнее, чем два цикла независимо.
Тем не менее, если вы хотите записать это как один цикл, одна идея состоит в том, чтобы подуматьо пространстве итераций , множестве пар, по которым вы перебираете.Прямо сейчас это выглядит так:
(0, 0) (0, 1), (0, 2), ..., (0, N-1)
(1, 0) (1, 1), (1, 2), ..., (1, N-1)
...
(N-1, 0) (N-1, 1), (N-1, 2), ..., (N-1, N-1)
Идея состоит в том, чтобы попытаться посетить все эти пары в порядке (0, 0), (0, 1), ..., (0, N-1), (1, 0), (1, 1), ..., (1, N-1), ..., (N-1, 0), (N-1, 1), ..., (N-1, N-1)
.Чтобы сделать это, обратите внимание, что каждый раз, когда мы увеличиваем i
, мы пропускаем N
элементов, тогда как когда мы увеличиваем j
, мы пропускаем только один элемент.Следовательно, итерация (i, j)
цикла будет отображаться в положение i * N + j
в линеаризованном порядке цикла.Это означает, что на итерации i * N + j
мы хотим посетить (i, j)
.Для этого мы можем восстановить i
и j
из индекса, используя простую арифметику.Если k
является текущим счетчиком цикла, мы хотим посетить
i = k / N (integer division)
j = k % N
Таким образом, цикл может быть записан как
for (int k = 0; k < N * N; ++k) {
int i = k / N;
int j = k % N;
}
Однако вы должны быть осторожны с этим, потому что N * N
может не вписаться в целое число и, следовательно, может переполниться.В этом случае вы захотите использовать двойной цикл for.Более того, введение дополнительных делений и модулей сделает этот код (потенциально) намного медленнее, чем двойной цикл for.Наконец, этот код гораздо сложнее для чтения, чем исходный код, и вам нужно быть уверенным, что вы предоставите агрессивные комментарии, описывающие, что вы здесь делаете.Опять же, я настоятельно советую вам не делать этого вообще, если у вас нет веских оснований подозревать, что существует проблема со стандартным двойным циклом for.
(Интересно, что здесь также можно использовать хитростьиспользуется для представления многомерного массива с использованием одномерного массива. Логика идентична - у вас есть двумерная структура, которую вы хотите представить с одномерной структурой.)
Надеюсь, это поможет!