LINUX.ORG.RU
ФорумTalks

Цикл for по матрице

 


0

1

Сижу, пишу программу с вложенными циклами методом копипаста, и возник вопрос. Умеют ли какие-нибудь языки программирования перебирать в цикле сразу несколько переменных? Наподобие:

for a,b := [0,0] to [Amax,Bmax] do begin
  ...сделать что-то с a и b...
end;

Использовать такой язык всё равно не смогу, поэтому в Talks.

★★★★★

Да на любом можешь наговнять, но зачем? Двухмерным массив не для того сделали чтобы его в строку разворачивать для неочевидного упрощения кода (в каком порядке он пойдет по массиву - сначала ряды, сначала столбцы, 1*1>2*2>3*3 etc?)

vostrik ★★★☆
()

Я в matlab'е вообще зачастую матрицы не перебираю, множество задач можно свести к их сложению, перемножению, выбору столбцов, транспонированию (в контексте лора звучит как-то не так), усреднению или ещё чему-нибудь. Заодно это позволяет прозрачно включить GPU Acceleration.

Sadler ★★★
()
Ответ на: комментарий от vostrik

Двухмерным массив не для того сделали чтобы его в строку разворачивать для неочевидного упрощения кода (в каком порядке он пойдет по массиву - сначала ряды, сначала столбцы, 1*1>2*2>3*3 etc?)

Как раз в моём случае порядок был неважен :)

Но порядок легко оговорить в стандарте. Например, перебирать переменные в порядке их перечисления. Или в обратном.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

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

vostrik ★★★☆
()
Ответ на: комментарий от vostrik

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

Да, а что? Случай достаточно распространённый, в Фортране, например, под него специальные оптимизации сделаны.

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

Зачем при движении по главной диагонали вторая переменная?

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

question4 ★★★★★
() автор топика
Ответ на: комментарий от iz_tabakerki

транспонированию (в контексте лора звучит как-то не так)

Неплохо, 8 пони/10

Что не так с транспонированием, и при чём тут пони?

question4 ★★★★★
() автор топика
Ответ на: комментарий от Sadler

транспонированию (в контексте лора звучит как-то не так)

Что не так с транспонированием?

И да, с операциями над матричами удобнее.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Да, а что?

Кроме того, что добавляет сложности при чтении и отладке и решается одной строкой кода и одной фигурной скобкой?

Зачем при движении по главной диагонали вторая переменная?

Затем, что массив не обязательно квадратный, что превращает главность диагонали в условность (но не задачу идти вдоль нее). Особенно в случае оптимизаций

vostrik ★★★☆
()
Ответ на: комментарий от Deleted

for i := 0 to Amax * Bmax do begin

Ну да, можно и так. Но это 3 лишних строки и 1 лишняя переменная. Читаемость падает. Уж лучше 2 вложенных цикла.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Гумка тебя подери, что за бред ты написал? Ты можешь это все накропать в одну строку и у тебя пременных на одну меньше - т.е. всего одна - i.

Deleted
()
Ответ на: комментарий от vostrik

одной фигурной скобкой

Не все языки в семействе Си :)

Затем, что массив не обязательно квадратный, что превращает главность диагонали в условность (но не задачу идти вдоль нее). Особенно в случае оптимизаций

Зачем идти вдоль диагонали в неквадратном массиве? Можно пример?

Если идти вдоль диагонали, одна координата однозначно выражается через другую. Или нет? Можно пример?

question4 ★★★★★
() автор топика
Ответ на: комментарий от Deleted

Гумка

В смысле? Ластик? Или презерватив? Или демократизатор?

Ты можешь это все накропать в одну строку

Ну да, можно. Вложенные for тоже можно. Но не положено :)

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Да пжалста - найти первый ряд ИЛИ столбец, в котором встречается искомое значение. Домен можно прилагать любой, задача встречалась тыщщу раз в разных областях. Обв, разумнее идти по диагонали, а не тупым перебором молотить ряд/столбец друг за другом, и в этом случае loop по 2х мерному массиву начинает иметь смысл. Но отладка этого, с учетом того, что массив 10*20 в этом случае стоит обходить иначе, чем 20*10, становится сильно неочевидной

vostrik ★★★☆
()
Ответ на: комментарий от iz_tabakerki

Догадайся с 3 раз, разрешаю воспользоваться sed.

В транспонировании sed найдёт пони, если не принять мер. В sed есть транслитерация. Твои реплики похожи на команды sed, но он их не примет. Дальше затык.

question4 ★★★★★
() автор топика
Ответ на: комментарий от vostrik

Обв

Что?

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

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

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Обв

Что?

Очевидно

Искомое значение в конце первого ряда, перебрал диагональ, ничего не получил

Перебрал 1*1, потом 2*2, потом 3*3 (в случае квадратной матрицы) и получил в самом конце (упс, не повезло. Вероятность найти быстрее все равно выше, чем в случае перебора в лоб). Движение вдоль диагонали != движение по диагонали

vostrik ★★★☆
()
Последнее исправление: vostrik (всего исправлений: 1)
Ответ на: комментарий от question4

В Haskell для контейнеров обычно определены фунции вроде map, filter и подобных, через которые и предлагается «сделать что-то с a и b», используя 0 for-ов :)

Softwayer ★★
()
#include <iostream>

class MIter {
public:
	struct value { int x, y; };

	class iterator {
	public:
		iterator(int xmin, int ymin, int xmax, int ymax, int cx, int cy)
			: xmin_{xmin}, ymin_{ymin}, xmax_{xmax}, ymax_{ymax},
			  cx_{cx}, cy_{cy}
		{}

		bool operator!=(const iterator &other) {
			return this->cx_ != other.cx_ || this->cy_ != other.cy_;
		}

		iterator &operator++() {
			cx_ += 1;
			if (cx_ >= xmax_) {
				cx_ = xmin_;
				cy_ += 1;
			}
			return *this;
		}

		value operator*() {
			value v;
			v.x = cx_;
			v.y = cy_;
			return v;
		}

	private:
		int xmin_, ymin_, xmax_, ymax_, cx_, cy_;
	};

	MIter(int xmin, int ymin, int xmax, int ymax)
		: xmin_{xmin}, ymin_{ymin}, xmax_{xmax}, ymax_{ymax}
	{}

	iterator begin() {
		return iterator(xmin_, ymin_, xmax_, ymax_, xmin_, ymin_);
	}

	iterator end() {
		return iterator(xmin_, ymin_, xmax_, ymax_, xmin_, ymax_);
	}

private:
	int xmin_, ymin_, xmax_, ymax_;
};


int main() {
	const int Amax = 5;
	const int Bmax = 5;

	for (auto a: MIter(0, 0, Amax + 1, Bmax + 1))
		std::cout << "(" << a.x << "," << a.y << ")\n";
}

i-rinat ★★★★★
()
Ответ на: комментарий от question4

Спасибо. Можно заодно пример кода?

> [(x,y) | x <- [0..2], y <- [0..3]]
[(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3)]

Вот тебе список индексов. А дальше проходись по нему чем хочешь. Типа такого:

> for_ [(x,y) | x <- [0..2], y <- [0..3]] $ \(a,b) -> putStrLn ("A " ++ show a ++ " B " ++ show b)
A 0 B 0
A 0 B 1
A 0 B 2
A 0 B 3
A 1 B 0
A 1 B 1
A 1 B 2
A 1 B 3
A 2 B 0
A 2 B 1
A 2 B 2
A 2 B 3

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от vostrik

Движение вдоль диагонали != движение по диагонали

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

Когда нужно обработать каждое сочетание индексов, а порядок не важен, метод неудобен.

question4 ★★★★★
() автор топика

Изврат конечно, но на двумерный массив всего один цикл

  int a ,b;
char s[10][10];

for(a=0,b=0;(a<10);(b<9)?(b++):(b=0,a++))
{
    s[a][b]=a;
}

BlackJack
()

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

Интересно, это у вас математическая задача? Обработка графики? В каких задачах, имея современные инструменты вроде хэш-массивов, оно сегодня используется?

gistart
()
Ответ на: комментарий от gistart

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

Например криптография.Это несколько разные вещи очень упрощенно массивы это это способ организации памяти,хэш-массивы это способ доступа к памяти.

BlackJack
()
Ответ на: комментарий от gistart

Интересно, это у вас математическая задача?

Это вообще не задача на массивы. Это стресс-тест серверов :) Гонял данные с одного на другой в разных сочетаниях, пока что-нибудь не отвалится. Поэтому 2 переменные — номер откуда, и номер куда. Просто в скрипте многократно скопипастил этот двойной цикл. Не сразу применять все варианты запросов к одной паре, а вначале применить ко всем парам серверов один вариант, потом второй, и т.д.

question4 ★★★★★
() автор топика
Ответ на: комментарий от BlackJack

for(a=0,b=0;(a<10);(b<9)?(b++):(b=0,a++))

Спасибо.

question4 ★★★★★
() автор топика
from itertools import product
for a, b in product(range(Amax), range(Bmax)):
    print(a, b)

или

for a, b in ((x, y) for x in range(Amax) for y in range(Bmax)):
    print(a, b)

deadNightTiger ★★★★★
()
Ответ на: комментарий от question4

Ну да. Что-то помимо Хаскеля так умеет?

Мой пример на питоне же.

Axon ★★★★★
()
Ответ на: комментарий от deadNightTiger

Часто нужны именно индексы, например, для доступа к соседним ячейкам.

Но ТС-то об этом не упоминал.

Axon ★★★★★
()

кложа умеет:

(for [x [1 2] y [1 2 3]] (prn x y))
; 1 1
; 1 2
; 1 3
; 2 1
; 2 2
; 2 3   
S-Mage ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.