1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!
| Флогримм |
28.10.2004 7:39
Сообщение
#1
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
вчера сел решать задачи на тему двумерных массивов - матриц и столкнулся с проблемой; какие можете посоветовать приемы программиования для алгоритмов, вида "заполнить матрицу по спирали, зигзагом" и т.д.
мне не конкретной задачи нужно решение, а метод в целом пришла в голову такая идея: написать процедуры движения по матрице в четырех направленияъ (вверх, вниз, влево, вправо) до тех пор, пока не встретим либо конец матрицы ("крайнюю стенку") или же уже заплненный алгоритм и циклически повторять их до тех пор пока не заполним всю матрицу... да, наверное так и попробую хотя мне кажется, что выход, который предложил выше не совсем правильный; может все можно свести все к основной (единственной формуле) формуле где меняться будет только значение i,j-счетчиков в цикле? вобщем матрицы для меня проблема; помогите чем могите; в книгах же только и делают, что задачки пишут, а концепцию разъясникть - :no: вот так а еще вопрос: 1)как в вин2к в ТП7 установить русскую раскладку клавы; 2)как прервать зациклившийся процесс? (Ctrl-Break и Ctrl-F2 не работают) зосим откланиваюсь, с уважением, Флогримм -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
![]() ![]() |
| Altair |
28.10.2004 8:12
Сообщение
#2
|
![]() Ищущий истину ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата как в вин2к в ТП7 установить русскую раскладку клавы; Это тема неоднократно обсуждалась! Методтаков: создать BET файл, где прописать русификатор и TP. Цитата как прервать зациклившийся процесс? (Ctrl-Break и Ctrl-F2 не работают) Прежде всего, зациклившихся процессов быть не должно! Везде где есть рекурсия, надо писать на всякий случай Код If keypressed then HALT; Это останов проги по нажатию люой клавиши. (пропиши модуль CRT) Цитата написать процедуры движения по матрице в четырех направлениях Это очень хорошие алгоритм. Лучше пожалуй (в смысле универсальности), не придумать! ТОлько это должны быть функции. Смысл в том, что достаточно указать алгоритм движения, и можно хаполнить любую матрицу как угодно... хм.. а это интересно, сейчас займусь этим... посмотрим что получится... -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
| Флогримм |
28.10.2004 9:02
Сообщение
#3
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
вот еще несколько вопросов, пожалуй, размещу здесь, влом новую тему создавать
1) как пользоваться операторами input/output? насколько это актуально? зачем нужно(хотя догадываюсь 2) как передавать параметры программе, запуская ее через командную строку? как оформить это в самой программе? зы вчера при компиляции программы, где использовались функции работы с файлами (assign, reset,close и т.д.) мой докторвэб выдал мне перл: "D:\TP\BIN\OLEG\PRACTP~1\LINES812.EXE инфицирован модификацией Ithaqua.12310" ;)) вот такой мя вэб умный потом комп проверил на наличие вирей, вроде чисто... Цитата Это очень хорошие алгоритм. Лучше пожалуй (в смысле универсальности), не придумать! Цитата Прежде всего, зациклившихся процессов быть не должно! Везде где есть рекурсия, надо писать на всякий случай это у мя не в рекурсивных алгоритма, в обычных циклах бывает в основном в результате очепяток.. бр-рр т.е. опечаток -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| volvo |
28.10.2004 9:16
Сообщение
#4
|
|
Гость |
Цитата как передавать параметры программе, запуская ее через командную строку? В меню Run -> Parameters вводишь параметры для передачи программе так, как если бы запускал ее через DOS (но НЕ включая имя самой программы)... Цитата как оформить это в самой программе? Получить доступ к параметрам командной строки можно с помощью функций ParamCount - (возвращает количество параметров) и ParamStr(i) (возвращает i-ый параметр в виде строки). Пример: Код var I: Word; begin for I := 1 to ParamCount do Writeln(ParamStr(I)); end. Сообщение отредактировано: volvo - 28.10.2004 9:16 |
| Altair |
28.10.2004 9:32
Сообщение
#5
|
![]() Ищущий истину ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата это у мя не в рекурсивных алгоритма, в обычных циклах бывает в основном в результате очепяток Да это неважно, все равно вставляй эту сроку. Цитата ) как пользоваться операторами input/output? насколько это актуально? зачем нужно(хотя догадываюсь )? почему упоминается только в старых книгах? Это не операторы, это переменные ИМХО.... их когда-то использовали ... Эта переменная типа FILE - определяет файл ввода\вывода по умолчанию... никто этим не пользуется особо, потому что неудобно, и вносит путанницу ИМХО... Лучше опредедлить файл как FILE и не мучаться -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
| Флогримм |
28.10.2004 10:19
Сообщение
#6
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
volvo, спасибо. Усвоил. Ща попробую.
Цитата Это не операторы, это переменные ИМХО.... их когда-то использовали ... Эта переменная типа FILE - определяет файл ввода\вывода по умолчанию... никто этим не пользуется особо, потому что неудобно, и вносит путанницу ИМХО... Лучше опредедлить файл как FILE и не мучаться ясно Цитата ТОлько это должны быть функции. почему? что будет результатом работы функции? конечная точка пройденного пути(текущая координата)? -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| Altair |
28.10.2004 10:26
Сообщение
#7
|
![]() Ищущий истину ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Цитата почему? Зависит от задачи. и от способа реализации... -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
| Флогримм |
1.11.2004 11:41
Сообщение
#8
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
вот как на мой взгляд лучше всего решать задачу на заполнение массива значениями по спирали
Код 01|02|03|04 12|13|14|05 11|16|15|06 10|09|08|07 ГЛАВНОЕ установить ПРИОРИТЕТ направеления движения! в данном примере это (->, \/, <-, /\) Код program spirall; uses crt; const Size=7; k=0; var mas:array[1..size,1..size]of shortint; i,j,a:integer; procedure draw; begin writeln; for i:=1 to size do begin for j:=1 to size do write(mas[i,j]:2,'|'); writeln; end; end; begin for i:=1 to size do for j:=1 to size do mas[i,j]:=k; clrscr; i:=1; j:=1; mas[i,j]:=1; for a:=1 to sqr(size) do begin write(i,'-',j,' '); if mas[i,j+1]=k then begin inc(j); mas[i,j]:=a+1; end else{если пустая ячейка справа, тогода перейти на эту ячейку и присвоить ей очередное значение а...} if mas[i+1,j]=k then begin inc(i); mas[i,j]:=a+1; end else {иначе, если пустая ячейка снизу, тогда...} if mas[i,j-1]=k then begin dec(j); mas[i,j]:=a+1; end else {иначе если пустая ячейка слева...} if mas[i-1,j]=k then begin dec(i); mas[i,j]:=a+1; end; {...пустая сверху...} end; draw; end. я вот код написал, но где-то ошибка если кто в задачу врубился, помогите... в комментария к коду именно тот приоритет, о котором я говорил, то есть если вся матрица пустая(все ячейки имеют значение 0), а текущее позиция, например, ячейка mas[1,1] то у нее рядом 2 свободных клетки - снизу и справа, но мы не можем двигаться вниз, т.к. у движения вправо более высокий приритет идея, надеюсь, понятна задавая, таким образом, приотритет и напрвление можно заполнять матрицы различними "узорами", не только спиральными -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| volvo |
1.11.2004 12:59
Сообщение
#9
|
|
Гость |
Смотри, что я наваял:
Код program spirall; uses crt; const Size=7; k=0; var mas:array[1..size,1..size]of shortint; i,j,a:integer; type direction = (go_right, go_down, go_left, go_up); var current: direction; function check_direction(i, j: integer): boolean; function next_direction(x: direction): direction; begin if x <> go_up then next_direction := succ(x) else next_direction := go_right end; var change: boolean; begin check_direction := true; change := false; case current of go_right: if (j = size) then change := true else if mas[i, j+1] <> k then change := true else exit; go_down: if (i = size) then change := true else if mas[i+1, j] <> k then change := true else exit; go_left: if (j = 1) then change := true else if mas[i, j-1] <> k then change := true else exit; go_up: if (i = 1) then change := true else if mas[i-1, j] <> k then change := true else exit; end; if change then current := next_direction(current); check_direction := false end; procedure draw; begin writeln; for i:=1 to size do begin for j:=1 to size do write(mas[i,j]:2,'|'); writeln; end; end; begin for i:=1 to size do for j:=1 to size do mas[i,j]:=k; clrscr; i:=1; j:=1; mas[i,j]:=1; for a := 1 to pred(sqr(size)) do begin while not check_direction(i, j) do; case current of go_right: inc(j); go_down : inc(i); go_left : dec(j); go_up : dec(i); end; mas[i, j] := succ(a) end; draw; end. Добавлено: Оптимизированный код... :D Код Uses Crt; Const size = 7; k = 0; Var mas: Array[1 .. size, 1 .. size] Of ShortInt; Type direction = (go_right, go_down, go_left, go_up); Var current: direction; {$F+} Function getPred(x: Integer): Integer; Begin getPred := Pred(x) end; Function getSucc(x: Integer): Integer; Begin getSucc := Succ(x) end; {$F-} Function check_direction(i, j: Integer): Boolean; Function next_direction(x: direction): direction; Begin If x <> go_up Then next_direction := Succ(x) Else next_direction := go_right End; Type TAxis = (isVert, isHoriz); TFunc = Function(x: Integer): Integer; Function check_range(is: TAxis; range: Integer; f: TFunc): Boolean; Begin check_range := True; Case is Of isVert: If (i = range) Then check_range := False Else If mas[f(i), j] <> k Then check_range := False; isHoriz: If (j = range) Then check_range := False Else If mas[i, f(j)] <> k Then check_range := False End End; Begin check_direction := True; Case current Of go_right: If check_range(isHoriz, size, getSucc) Then exit; go_down: If check_range(isVert, size, getSucc) Then exit; go_left: If check_range(isHoriz, 1, getPred) Then exit; go_up: If check_range(isVert, 1, getPred) Then exit; end; current := next_direction(current); check_direction := False End; Procedure draw; Var i, j: Integer; Begin WriteLn; For i := 1 To size Do Begin For j := 1 To size Do Write(mas[i,j]:2,'|'); WriteLn End End; Var i, j, a: Integer; Begin For i := 1 To size Do For j := 1 To size Do mas[i, j] := k; ClrScr; i := 1; j := 1; mas[i, j] := 1; For a := 1 To Pred(Sqr(size)) Do Begin While not check_direction(i, j) Do; Case current Of go_right: Inc(j); go_down : Inc(i); go_left : Dec(j); go_up : Dec(i) End; mas[i, j] := Succ(a) End; draw End. Сообщение отредактировано: volvo - 1.11.2004 23:17 |
| Флогримм |
1.11.2004 13:24
Сообщение
#10
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
Вольво, спасибо, ща попробую разобраться.
А с моим алгоритмом кто-нить поможет? в чем моя ошибка? -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| volvo |
1.11.2004 13:39
Сообщение
#11
|
|
Гость |
Флогримм
У твоего алгоритма есть очень существенный недостаток: ты не проверяешь, достигло ли значение i или j максимально возможного для данной матрицы (т.е. значения size...). Сообщение отредактировано: volvo - 1.11.2004 14:39 |
| Флогримм |
1.11.2004 15:00
Сообщение
#12
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
volvo
а зачем проверять? вот смотри: доходим до правого края матрицы, пусть size=4 (т.е. текущая позиция mas[1,4] ), на следующей же итеррации цикла, у нас есть такой условный оператор Код ... if mas[i,j+1]=k then begin inc(j); mas[i,j]:=a+1; end else if mas[i+1,j]=k then begin inc(i); mas[i,j]:=a+1; end else ... т.е. мы проверяем есть ли у ячейки mas[1,4] "свободный"(значение ячейки =0) сосед: да - inc(j); mas[i,j]:=a+1; нет - переходим к проверке других "свободных" соседей поэтому можно избежать проверки встречи с границей массива size аналогичная проверка происходит, когда мы встречаемся с нижней границей или левой и т.д. тока че то мой алгоритм неработает -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| volvo |
1.11.2004 15:13
Сообщение
#13
|
|
Гость |
Цитата а зачем проверять? А попробуй откомпилировать и запустить свою программу в таком режиме: Код {$R+} Сообщение отредактировано: volvo - 1.11.2004 15:14 |
| Amro |
1.11.2004 17:05
Сообщение
#14
|
![]() Пионер ![]() ![]() Группа: Пользователи Сообщений: 146 Пол: Мужской Репутация: 2 |
Можно здеся посмотреть
http://forum.pascalnet.ru/forum/index.php?showtopic=162 Тема ещё в том году обсуждалась, там есть несколько вариантов решения :D Кстати Oleg_Z Неплохо было бы в ЧаВо такую темку создать "Олимпиадные задачи" :yes: -------------------- Закон иудеев: Семь раз отмерь, один отрежь.
Закон экономии: Семь раз отмерь, семь раз отрежь. Закон программиста: Семь раз отрежь, ошибся, отмерь. |
| Altair |
1.11.2004 17:19
Сообщение
#15
|
![]() Ищущий истину ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Согласен. Можно. Так кто тебе мешает это сделать?
Внесу, как появится материал... -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
| Флогримм |
2.11.2004 0:15
Сообщение
#16
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
Цитата {$R+} Код 201 Range check error (Ошибка при проверке границ). Ошибка генерируется операторами, скомпилированными в состоянии {$R+}, при возникновении одной из следующих ситуаций: индексное выражение массива находилось вне допустимого диапазона; была осуществлена попытка присвоить переменной значение, находящееся вне диапазона переменной; была осуществлена попытка передать значение, находящееся вне допустимого диапазона, в качестве параметра процедуре или функции. это я понимаю, но у мя же есть проверка! если мы находимся на "приграничной" ячейке массива, мы НЕ МОЖЕМ перещагнуть, выйти за границы массива на следующую ячейку! если size=4 то мы НЕ МОЖЕМ попасть на mas[1,5] и т.д.!! не оебята, свой код мне ненадо! ненадо за меня код писать, я прошу помочь мне ошибку найти в моем; можно поробовать такое условие ввести: Код ... if (mas[i,j+1]=k) and (j<=size) then begin inc(j); mas[i,j]:=a+1; end else if (mas[i+1,j]=k) and (i<=size) then begin inc(i); mas[i,j]:=a+1; end else .... где в моем коде ошибка? помогите найти -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| volvo |
2.11.2004 1:13
Сообщение
#17
|
|
Гость |
Цитата мы НЕ МОЖЕМ попасть на mas[1,5] но при прогоне программы мы туда-таки попадаем !!! |
| Флогримм |
2.11.2004 7:11
Сообщение
#18
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
я понимаю!! прога работает НЕПАРВИЛЬНО! но алгоритм, на мой взгляд - правильный, попробуй устно прогнать его для нескольких значений, все получается вроде
где моя ошибка?? -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
| Бродяжник |
2.11.2004 10:51
Сообщение
#19
|
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 206 Пол: Мужской Репутация: 3 |
Флогримм
Вы слишком широко понимаете смысл слов "у ячейки есть свободная соседняя ячейка". Вы непроизвольно предполагаете, что это выражение значит, что а) ячейка с индексами i,j существует для данной матрицы, т.е. выражение mas[i,j] имеет смысл, а также, что б) значение mas[i,j] равно заданному к. Однако у компьютера другое мышление. Если при компиляции отключена проверка Range check, то компилятор просто генерит код, в котором адресация [i,j] заменяется относительными адресами памяти. И в этом случае адрес памяти, соответсвующий адресации [1,5] для матрицы 4х4, скорее всего, будет соответствовать адресации [2,1]. И по этому адресу записано корректное с точки зрения программы значение, а именно значение к, указывающее на то, что ячейка свободна. При этом программа не знает, что полученное значение было взято вовсе не из мифической ячейки [1,5]. Она смело переходит к не менее мифической ячейке [1,6] (а на деле [2,2])... и снова находит там значение к. "Рулез!"- думает программа. Поэтому я бы заменил прямое обращение к ячейкам [i,j] на вызов функции Код function freemas(i,j: shortint): boolean; begin if (i<1) or (i>size) or (j<1) or (j>size) then freemas:=false else freemas:=(mas[i,j]=k); end; При этом общая структура Вашего алгоритма практически не изменится. Просто вместо Код if mas[i,j]=k then будет Код if freemas(i,j) then ...Я неправ? Сообщение отредактировано: Бродяжник - 2.11.2004 10:53 |
| Флогримм |
2.11.2004 20:56
Сообщение
#20
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 253 Пол: Мужской Репутация: 4 |
Бродяжник!
Ваше сообщение - это то, чего я так долго ждал в этой теме! спасибо огромное! я с вашей помощи наконец решил эту задачу. Ниже приведен код. Код program spirall; uses crt; const Size=7; k=-1; {"пустая ячейка" содержит значение k} var mas:array[1..size,1..size]of shortint; i,j,a:integer; function freemas(i,j: shortint): boolean; {(с) Бродяжник - функция проверяет,} begin {является ли ячейка с координатами i,j "пустой ячейкой"} if (i<1) or (i>size) or (j<1) or (j>size) then freemas:=false else freemas:=(mas[i,j]=k); end; procedure draw; {печать массива} begin writeln; for i:=1 to size do begin for j:=1 to size do write(mas[i,j]:2,'|'); writeln; end; end; begin for i:=1 to size do for j:=1 to size do mas[i,j]:=k; {заполнение массива "пустыми ячейками"} clrscr; i:=1; j:=1; mas[i,j]:=1; {algorithm} for a:=1 to sqr(size)-1 do begin if (freemas(i-1,j)) and (not freemas(i,j-1)) then begin dec(i); mas[i,j]:=a+1; end else if freemas(i,j+1) then begin inc(j); mas[i,j]:=a+1; end else if freemas(i+1,j) then begin inc(i); mas[i,j]:=a+1; end else if freemas(i,j-1) then begin dec(j); mas[i,j]:=a+1; end else continue; end; {/algorithm} draw; end. Пришлось чуть-чуть исправить алгоритм, т.е. я установил более высокий приоритет на движение вверх и немного изменил условия этого движ-я (идти вверх, только если верхняя ячейка пуста, а правая заполнена). Можете проверить прога работает. Я считаю, что это один из наиболее универсальных алгоритмов, потому что: 1) количество действий минимальное, для матрицы порядка n оно равно n*n 2) изменяя очередность проверки(приоритет направления) и условия перехода на новую ячейку можно задавать многие виды движений! Например, поменял местами только строки и движ-е уже абсолютно иное, чсмотрите Код if (freemas(i-1,j)) and (not freemas(i,j-1)) then begin dec(i); mas[i,j]:=a+1; end else if freemas(i+1,j) then begin inc(i); mas[i,j]:=a+1; end else if freemas(i,j+1) then begin inc(j); mas[i,j]:=a+1; end else if freemas(i,j-1) then begin dec(j); mas[i,j]:=a+1; end else continue; в данном случае движ-е следующее: Код 01|08|09|16 02|07|10|15 03|06|11|14 04|05|12|13 Не в обиду Вольво будет сказано, но по-моему мой алгоритм более лаконичен и понятен, чем его продвинутые вышеприведенные алгоритмы. 2 Олег_З если хочешь, можешь включить этот алгоритм в ФАК по матрицам. только я до сих пор не пойму, почему компиллятор ведет себя именно так, как описал Бродяжник (я понял как ведет, только не понял почему, не логичное поведение какое-то) -------------------- Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
|
![]() ![]() |
|
Текстовая версия | 8.12.2025 19:59 |