|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Алгоритмы обхода матрицы |
|
Алгоритмы обхода матрицы
|
Ветеран Сообщения: 1404 |
Задача следующая. Есть матрица размера mxn
Нужно отсортировать элементы матрицы и пройти ее по часовой стрелке от начала до центра, располагая в матрице отсортированные ее элементы. Например, если дана матрица A(m,n) {a(i,j)-элементы} и m=n=3, то проход a(1,1) -> a(1,2) ->a(1,3) -> a(2,3) -> a(3,3) -> a(3,2) -> a(3,1) -> a(2,1) --> a(2,2) Насколько эффективен будет следующий алгоритм обхода: сначала делаем поворот (с располаганием элементов) на 3 четверти, затем циклично до конца повороты на 2 четверти. Какие более эффективные алгоритмы можно использовать? 'Расположить элементы матрицы по часовой стрелке в возрастающем порядке Dim a(),x(), sx,posy,posx,numx,numy,k,i,j,l,m,n,s, u, msg, msgst,msgp, nn,tmp input() msg=sort(x) sx=split(msg,"~") msgp=arr_to_string(sx,1) msgst=arr_to_string(a,2) u=0 l=0 numy=Ubound(a,1) numx=Ubound(a,2) posy=0 posx=0 i=0 ''''''''''один поворот на 3 четверти''''''''''''' For j=posx To numx a(i,j)=eval(sx(l)) l=l+1 Next j=j-1 numx=posx posx=j For i=posy+1 To numy a(i,j)=eval(sx(l)) l=l+1 Next i=i-1 numy=posy posy=i if m<>0 then For j=posx-1 To numx Step -1 a(i,j)=eval(sx(l)) l=l+1 Next j=j+1 numx=posx posx=j numy=numy+1 end if '''''''''''следующие повороты на 2 четверти'''''''''' nn=1 while (l<Ubound(sx)) if ((nn Mod 2) <> 0) then if nn>2 then numy=numy+1 For i=posy-1 To numy Step -1 a(i,j)=eval(sx(l)) l=l+1 Next i=i+1 numy=posy posy=i For j=posx+1 To numx-1 a(i,j)=eval(sx(l)) l=l+1 Next j=j-1 numx=posx posx=j nn=nn+1 else For i=posy+1 To numy-1 a(i,j)=eval(sx(l)) l=l+1 Next i=i-1 numy=posy posy=i if nn>1 then numx=numx+1 For j=posx-1 To numx Step -1 a(i,j)=eval(sx(l)) l=l+1 Next j=j+1 numx=posx posx=j nn=nn+1 end if wend ''''''''' Вывод матрицы ''''''''' msg = arr_to_string (a,2) msgBox("Последовательность: "&vbcrlf& msgp&vbcrlf& _ "Начальная матрица: "&vbcrlf& msgst&vbcrlf&_ "Конечная матрица: "&vbcrlf& msg&vbcrlf) '''''''''''''''''''''''''''''''''''''''''''''''''''''' Function sort (x()) Dim i,j,s For i=0 To Ubound(x)-1 For j=i+1 To Ubound(x) If (x(i)>x(j)) then tmp=x(j) x(j)=x(i) x(i)=tmp end if next next s=join(x,"~") sort=s End Function Sub input() Dim k,i,j,t k=0 m=inputbox("Размерность по y?") while (not isnumeric(m) or isempty(m) or isnull(m) or m<0) m=inputbox("Введено некорректное значение. Введите размерность по y") wend n=inputbox("Размерность по x?") while (not isnumeric(n) or isempty(n) or isnull(n) or n<0) n=inputbox("Введено некорректное значение. Введите размерность по x") wend Redim a(m,n) For i=0 To Ubound(a,1) For j=0 To Ubound(a,2) t=inputbox("Введите a("&i&","&j&")") while (not isnumeric(t) or isempty(t) or isnull(t)) t=inputbox("Введено некорректное значение. Введите a("&i&","&j&")") wend Redim Preserve x(k) a(i,j)=t x(k)=eval(a(i,j)) k=k+1 Next Next End Sub Sub arr_print(p(), r) Dim i,j Select Case r Case "1" For i=0 To Ubound(p) msgBox "p("&i&")/"&p(i)&"/"&vbcrlf Next Case "2" For i=0 To Ubound(p,1) For j=0 To Ubound(p,2) msgBox "p("&i&","&j&")="&p(i,j)&vbcrlf Next Next case else MsgBox("Not supported") End Select End Sub Function arr_to_string(p(), r) Dim msg,i,j msg="" Select Case r Case "1" For i=0 To Ubound(p) msg=msg & p(i) & " " Next msg=msg&vbcrlf Case "2" For i=0 To Ubound(p,1) For j=0 To Ubound(p,2) msg=msg & p(i,j) & " " Next msg=msg&vbcrlf Next case else MsgBox("Not supported") End Select arr_to_string=msg End Function |
|
Отправлено: 09:04, 25-10-2006 |
Googler Сообщения: 3665
|
Профиль | Отправить PM | Цитировать 1. Хорошо бы иметь таблицу преобразования (ТП) между координатами элемента в матрице и положением в одномерном массиве "раскрученной спирали", тогда заполнение выполняется за один проход... К примеру для матрицы 3x3 таблица преобразования будет (x,y) = {(1,2) (1,3) (2,3) (3,3) (3,2) (3,1) (2,1) (2,2)}, т.е. по сути это двумерный массив указателей.
2. Теперь как можно построить ТП. Допустим, мы можем построить ее для одного оборота обхода матрицы (MxN) начав с левого верхнего угла, т.е. имеем ф-цию Fun (N, M, I, J), добавляющую в конец глобальной ТП координаты обхода (I, J - "координаты" начала обхода). Так вот, полный путь состоит из последовательности: Fun (N,M, 0,0) --> Fun (N-2,M-2, 1,1) --> Fun (N-4,M-4, 2,2) ... пока размерность массива >0. 3. Алгоритм Fun (M, N, I, J) линеен и состоит из четырех отрезков: - y=J, x увеличивается от I до I+N-1 - x=I+N-1, y увеличивается от J до J+M-1 - y=J+M-1, x уменьшается от x=I+N-1 до I - x=I, y уменьшается от J+M-1 до J+1 З.Ы. Это только общий алгоритм... Звиняюсь, но из вашего кода я мало чего понял, и про "четверти" с "поворотами" тоже. |
Отправлено: 12:50, 25-10-2006 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 1404
|
Профиль | Отправить PM | Цитировать Цитата:
Три четверти поворота это проход от a(1,1) до a(3,1) - по 2 строкам и столбцу В коде делается следующее. Задаются начальные значения позиции в матрице и конечные значения: 1. проход по первой строке (четверть от полного поворота по часовой стрелке от a(1,1) до a(1,1)). После каждой четверти поворота меняем начальные значения на конечные. Строка(y) фиксируется, столбцы(x) меняются. 2. проход по последнему столбцу (вторая четверть поворота). Столбец(x) фиксируется, строки(y) меняются. 3. проход по последней строке (четверть поворота - всего 3/4 поворота) Заводится цикл, зависящий от переменной, показывающей четный или нечетный проход, чтобы знать, надо ли уменьшать индексы или нет: 1. проход по столбцу 2. проход по строке После каждого полного поворота уменьшается счетчик, показывающий конечные значения По-моему вы предложили то же самое.. Есть ли еще какие-нибудь способы? |
|
------- Отправлено: 16:09, 25-10-2006 | #3 |
![]() Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать есть, их полно. Правда чем дальме - тем более извращённый способ получается.
Например, сведём всё к одной операции прохода строчки и одной операции поворота матрицы (всё это в цикле). в цикле: 1. прошли верхнюю строчку 2. повернули на 90 CCW (кто фотошоп видел, поймёт) дальше варианты: копировать матрицу или поворачивать координатную ось. Дешевле повернуть ось (понятней - наоборот). Так и сделаем! // извиняюсь, что пишу не на языке вопроса, но если идея зацепит, попробую перевести class pass_matrix { static const int gwidth = 10; // начальная ширина static const int gheight = 20; // начальная высота int matrix[gwidth*gheight]; int width; // ширина int height; // высота int a, b, c, d; // преобразование координат // x1 = a*x + b // y1 = c*y + d int x, y; // смещение void print() { std::cout << "{" << x << ", " << y << "}: " << matrix[x + y*qwidth] << "\n"; } public: pass_matrix() : matrix(), width(gwidth), height(gheight), a(1), b(0), c(1), d(0), x(0), y(0) { // начальная позиция: // 0123 // 0x->. // 1.... // 2.... } private: void step() { // делаем один шаг x += a; y += b; } void rotate() { // шаг назад // 0123 // 0....x // 1...| // 2...v x += c - a; y += d - b; // поворот матрицы (направления) int a1 = c; int b1 = d; int c1 = -a; int d1 = -b; a = a1; b = b1; c = c1; d = d1; // поворот и усечение размеров --height; std::swap(width,height); } public: void main() { while (0<height) { for (int w=width; 0<=--w; step()) { print(); } rotate(); } } }; |
Последний раз редактировалось pva, 25-10-2006 в 22:25. Отправлено: 22:07, 25-10-2006 | #4 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
C/C++ - [решено] Нахождение обратной матрицы методом Гаусса и рассширенной матрицы | D.Y. | Программирование и базы данных | 64 | 06-05-2011 22:59 | |
Доступ - [решено] Способы обхода закрытого реестра | Игорь Анатольевич | Microsoft Windows 2000/XP | 21 | 12-12-2008 02:10 | |
Java - Капча и способы её обхода. | vaniak | Программирование и базы данных | 2 | 26-05-2008 17:47 | |
Программные средства обхода firewall | mzu | Сетевые технологии | 5 | 07-05-2004 23:37 | |
алгоритмы поиска. | Vlad Drakula | Программирование и базы данных | 9 | 16-01-2004 09:09 |
|