Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.12.2009, 18:27
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
Восклицание Сортировка в динамической памяти

Помогите найти ошибку. Написал на паскале небольшой код.

Смысл в том чтобы сортировать двунаправленное кольцо, никак не получается. Вот мой код:

Код:
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  
Старый 12.12.2009, 21:26
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
По умолчанию

ну что ребят, не подскажете как быть?
Ответить с цитированием
  #3  
Старый 12.12.2009, 23:24
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Как у вас реализована inkol
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #4  
Старый 13.12.2009, 00:07
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
Восклицание

Код:
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  
Старый 13.12.2009, 00:31
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Что-то я раньше как-то не сталкивался с Eof без указания в явном виде дескриптора на файла - ну допустим. Но вот Read без указания на дескриптор файла... что-то я тут неуверен, что это правильно работает. Указатель в файле вроде не движется и получается бесконечный цикл.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #6  
Старый 13.12.2009, 01:11
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Во первых, не понятно условие: 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  
Старый 13.12.2009, 09:16
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
Восклицание

Итак поясняю.

Как я писал выше - пишется это на 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  
Старый 13.12.2009, 09:25
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

про while not eof do - утверждать ничего не буду, хотя на мой взгляд мне кажется синтаксис неправильным. Для начала разберись со строками:
Код:
 ...
 q:=b;
 while (q<>b) or (x<q^.d) do
 ...
1) ты не попадаешь в цикл из-за (q<>b), так как на первой итерации цикла и q и b равны nil;
2) так как на первой итерации цикла q = b (nil), то q^.d - вероятнее всего возвращает ошибку.
Ответить с цитированием
  #9  
Старый 13.12.2009, 09:47
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Вообще, для начала, нужно словами сформулировать алгоритм. А после его воспроизводить.
Как я понял, основная задача у тебя следующая, принимать значения с клавиатуры, и вставлять их в двунаправленное кольцо, попутно сортируя (то есть, находя место для вставки), возникает вопрос, в организации кольца, (если это не двунаправленная очередь), само по себе кольцо не может быть отсортировано, так как, в каком либо месте будет образовываться перелом, где рядом будут стоять максимальное и минимально значение. Поэтому алгоритм сортировки, тот же самый, что и для однонаправленной очереди, (так как для сортировки нам достаточно одного направления).
К самому алгоритму:
1) получаем число x с клавиатуры
2) смотрим есть элементы в очереди
2а) если нет, то добавляем первый элемент
2б) если да, то ищем место куда вставим новый элемент, а именно, пробегаем всю очередь, и ищем максимальный элемент, когда находим его, вставлям за ним новый элемент.
Вроде все просто, переписывай, а после посмотрим, что получится.
Ответить с цитированием
  #10  
Старый 13.12.2009, 10:08
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 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  
Старый 13.12.2009, 10:41
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
По умолчанию

Извиняюсь, неправильно написал..

вот исправил

Код:
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  
Старый 13.12.2009, 10:50
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
По умолчанию

снова ошибка. сортировка не полностью работает

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  
Старый 13.12.2009, 14:05
ХодячийБаг ХодячийБаг вне форума
Прохожий
 
Регистрация: 12.12.2009
Сообщения: 8
Репутация: 10
По умолчанию

проблему решил, спасибо.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 05:16.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025