![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Помогите найти ошибку. Написал на паскале небольшой код.
Смысл в том чтобы сортировать двунаправленное кольцо, никак не получается. Вот мой код: Код:
type dat = integer; colob=^obd; obd = record ri,le: colob; // ri - укзатель на правый объект, le - на левый соответственно d: dat; // данное end; ... var b,e,q,ql: colob; x: dat; ... b:=nil; e:=nil; checkeof := true; while not eof do begin read(x); q:=b; while (q<>b) or (x<q^.d) do begin if x<=q^.d then begin ql:=q; q:=q^.ri; end; inkol(b,e,ql,x); // inkol - процедура добавления значения x слева от адреса ql. b,e - характеристика кольца (начало, конец), x данное, которое вводим. end; end; вероятно while циклится.. Ошибка "Runtime Error" вылезает после исполнения. Помогите пожалуйста, заранее спасибо. (Язык Pascal) p.s. сортировку производить при вводе входного потока Последний раз редактировалось ХодячийБаг, 12.12.2009 в 18:30. |
#2
|
|||
|
|||
![]() ну что ребят, не подскажете как быть?
|
#3
|
||||
|
||||
![]() Как у вас реализована inkol
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#4
|
|||
|
|||
![]() Код:
procedure inkol(var B,E: colob; al:colob; nd: dat); var ar,q: colob; begin new(q); q^.d := nd; if al=E then E := q; if al = nil then begin ar := B; al := E; B := q; end else ar := al^.ri; al^.ri := q; ar^.le := q; q^.ri := ar; q^.le := al; end; Работает ввод отично, проверял. проблема в самой сортировке. Либо поставил не так условие, либо не так устроил цикл. тоесть код Код:
while not eof do begin read(x); inkol(b,e,nil,x); end; внутри этой конструкции необходимо сделать сортировку. Программа циклится во внутреннем while и вылетает. В чем ошибка не понимаю, вот и прошу помощи. Заранее спасибо! Последний раз редактировалось ХодячийБаг, 13.12.2009 в 00:13. |
#5
|
||||
|
||||
![]() Что-то я раньше как-то не сталкивался с Eof без указания в явном виде дескриптора на файла - ну допустим. Но вот Read без указания на дескриптор файла... что-то я тут неуверен, что это правильно работает. Указатель в файле вроде не движется и получается бесконечный цикл.
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#6
|
|||
|
|||
![]() Во первых, не понятно условие: while (q<>b), когда перед этим стоит q:=b;, то есть, получается ты даже не попадаешь в этот цикл.
Дальше, ты хочешь пробежать весь круг, при том b = начальный элемент, но по коду выше мы видим что он равен нулю b:=nil; притом в процедуру incol (где у тебя изменяет значение b) мы не попадаем, опять же из-за while (q<>b). И Cтрадалецъ скорее всего прав, while not eof do - скорее всего равносильно фразе while true do, то есть если работа с файлом, то вид должен был быть while not eof(F) do, если у тебя только eof функция не переопределена., ну и конечно же, read(x) то же сомневает, так как read(x) ожидает ввод данных с клавиатуры, а если это должно читаться из файла, то должна быть передана ссылка на файл, вида: Read(F, x) ; , где F - ссылка на открытый файл, а если это ввод данных (опять противоречие while not eof do - вначале у нас нет элементов, значит not eof = false, тоже не попадаем в цикл), то лучше было бы сначала в цикле собрать эти данные, а потом их отсортировать, а не совмещать эти процессы. Ну и наконец ошибка скорее всего возвращается словами ... or (x<q^.d) ..., так как при входе в цикл q = b; а b как мы помним ранее = nil, соответственно q^.d = Error) Советую переписать весь алгоритм. Последний раз редактировалось Asinkrit, 13.12.2009 в 01:27. |
#7
|
|||
|
|||
![]() Итак поясняю.
Как я писал выше - пишется это на Pascal. Если вы не заметили, то я поставил перед while not eof do, checkeof := true;. Это оначает, что если я введу на экран: 1 2 3 4 5 6 7 8 9 10 11 и нажму Ctrl+Z, то тогда пойдет цикл так: read(x->1)...read(x->2)... ...read(x->11) Где вы взяли файлы? Это динамическая память. А not eof "Не конец входного потока". Цикл не бесконечный, а да тех пор пока не нажму Ctrl+Z (благодаря Checkeof := true); Получается итерационный цикл с вводом данных в любом количестве Это первое. Второе - вот по поводу самой сортировки и есть загвоздка.. Я немного потерял логическую цепочку. Вот и прошу подправить в коде. Что и на что нужно заменить? спасибо. |
#8
|
|||
|
|||
![]() про while not eof do - утверждать ничего не буду, хотя на мой взгляд мне кажется синтаксис неправильным. Для начала разберись со строками:
Код:
... q:=b; while (q<>b) or (x<q^.d) do ... 2) так как на первой итерации цикла q = b (nil), то q^.d - вероятнее всего возвращает ошибку. |
#9
|
|||
|
|||
![]() Вообще, для начала, нужно словами сформулировать алгоритм. А после его воспроизводить.
Как я понял, основная задача у тебя следующая, принимать значения с клавиатуры, и вставлять их в двунаправленное кольцо, попутно сортируя (то есть, находя место для вставки), возникает вопрос, в организации кольца, (если это не двунаправленная очередь), само по себе кольцо не может быть отсортировано, так как, в каком либо месте будет образовываться перелом, где рядом будут стоять максимальное и минимально значение. Поэтому алгоритм сортировки, тот же самый, что и для однонаправленной очереди, (так как для сортировки нам достаточно одного направления). К самому алгоритму: 1) получаем число x с клавиатуры 2) смотрим есть элементы в очереди 2а) если нет, то добавляем первый элемент 2б) если да, то ищем место куда вставим новый элемент, а именно, пробегаем всю очередь, и ищем максимальный элемент, когда находим его, вставлям за ним новый элемент. Вроде все просто, переписывай, а после посмотрим, что получится. |
#10
|
|||
|
|||
![]() Супер, сделал по пунктам, получилось вот что:
Код:
while not eof do begin t:= nil; read(x); // получаем число if b = nil then // смотрим есть ли элементы в очереди inkol(b,e,nil,x) // если нет то добавляем else while q<> B do // если есть ищем максимальное (t указатель на максимальное) begin if q^.d > t^.d then t := q; q:=q^.ri; end; inkol(b,e,t,x); // вводим за максимальным end; всё, теперь сортирует без ошибок.. Но почемуто при вводе кольца, например: 1 2 3 4 5 6 7 8 9 выдает 9 8 7 6 5 4 3 2 1 1 тоесть добавляется лишняя единица. Ведь поидее while not eof уже должен был не проходить еще раз внутреннее тело, а он прошел и опять проработал inkol. Последний раз редактировалось ХодячийБаг, 13.12.2009 в 10:23. |
#11
|
|||
|
|||
![]() Извиняюсь, неправильно написал..
вот исправил Код:
while not eof do begin t:= nil; q:=B; read(x); // получаем число if b = nil then // смотрим есть ли элементы в очереди inkol(b,e,nil,x) // если нет то добавляем else while q<> E do // если есть ищем максимальное (t указатель на максимальное) begin if q^.d > t^.d then t := q; q:=q^.ri; end; inkol(b,e,t,x); // вводим за максимальным end; |
#12
|
|||
|
|||
![]() снова ошибка. сортировка не полностью работает
p.s. при вводе большого разброса происходит вот что: ввод 7 3 9 8 1 2 0 6 кольцо 6 0 2 1 8 9 3 7 после сортировки 6 0 2 1 8 9 3 7 тоесть он даже не сортировал кольцо. оно как и было так и осталось Последний раз редактировалось ХодячийБаг, 13.12.2009 в 10:57. |
#13
|
|||
|
|||
![]() проблему решил, спасибо.
|