Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Задача на списки.

Автор: QDe5n1K 22.11.2004 20:25

Люди помогите!!! Плз... Задача звучит так:
"ВВодится некоторая последовательность букв русского алфавита и записывается в памяти в виде линейного списка. Определить упорядочена ли последовательность по алфавиту( если нет, то упорядочить), заменить выбранную K-ую букву на Q-ю, поменять местами первую и последнюю буквы...
Люди, пожалуйста, подскажите как это делать и приведите примеры кусочков кода (полный мне не нужен, хочу сам разобраться, но для этого нужно небольшое ускорение) Пожалуйста, подскажите что и как...

Автор: APAL 22.11.2004 20:28

http://forum.pascal.net.ru/index.php?showtopic=2706

Автор: QDe5n1K 24.11.2004 21:26

Почитал, многое понял...
Но тогда подскажите, в чем может быть ошибка в этой процедуре:

Код

procedure open(var p:plist;var a:char);
var filex:text;
   s:string;
begin
nameoffile(s);   {задаю имя файла другой процедурой}
assign(filex,s);          
reset(filex);
while not eof(filex) do
     begin
     new(p);
     p^.next:=nil;
     readln(filex, p^.a);
     p:=p^.next;
     end;
while p^.next<>nil do
begin
write(p^.a,' ');
p:=p^.next;
end;
readkey;
end;

в результате выполнения всего этого беспредела мне выдается 6 очень странных сиволов, совсем не похожих на, например, 26 букв английского алфавита... в чем здесь ошибка ? подскажите плз smile.gif

Автор: volvo 24.11.2004 21:44

QDe5n1K
Код должен выглядеть вот так:

Код

procedure open(var p:plist;var a:char);
var pp: plist;
...
while not eof(filex) do
    begin
    new(pp); {берем новый элемент из "кучи"}
    pp^.next:=p; {его "следующему" значению }
    readln(filex, pp^.a); {записываем в новый элемент данные}
    p:=pp; {а теперь при следующем выделении данных будем считать "новый" элемент последним, т.е. старым... :)}
    end;
...

Автор: QDe5n1K 25.11.2004 3:45

Ладно, вот еще smile.gif
Я собираюсь поменять число под номером P на число под номером Q...

Код

procedure change_p_to_q(var g:plist; var a:char);
var     l,p,q:word;
        x:char;
begin
writeln('Введите номер числа, которое вы хотите заменить');
readln(p);
writeln('Введите номер числа, на которое вы хотите поменять число под номером',p);
readln(q);
l:=0;
while l<>j do    {здесь я пытаюсь искать букву под номером q - то, на что буду менять}
    begin
       l:=l+1; g:=g^.next; x:=g^.next^.a;
    end;
l:=0;
while l<>i do     {здесь ищу ту букву, которую нужно поменять - p}
begin l:=l+1 g:=g^.next; end;
g^.a:=x;           {собственно присваиваю символьной переменной,  находящейся по этому адресу значение x, то бишь значение символа под номером q}
end;

Блин, ну что здесь не так... обьясните пожалуйста, что же я опять не так делаю?

Автор: volvo 25.11.2004 4:15

QDe5n1K
Если честно, я не совсем понял, что нужно найти, но вообще-то, чтобы найти элемент списка под номером X, пользуются такой конструкцией:


writeln('Введите номер числа, которое вы хотите найти'); readln(p);
while p<>0 do
 begin
   g:=g^.next; dec(p)
 end;

то есть вышеприведенный код может быть переписан вот так:

procedure change_p_to_q(var g:plist; var a:char);
var p,q:word;
 x:char;
 T: plist; {обязательно сохраняем исходное значение G }
begin
 T := g;
 writeln('Введите номер числа, которое вы хотите заменить'); readln(p);
 writeln('Введите номер числа, на которое вы хотите поменять число под номером',p); readln(q);
 while q<>0 do    {здесь я пытаюсь искать букву под номером q - то, на что буду менять}
   begin
      g:=g^.next; dec(q)
   end;
 x := g^.a; { сохраняем букву, на которую будем менять }

g := T; { восстанавливаем список }
while p<>0 do     {здесь ищу ту букву, которую нужно поменять - p}
 begin
   dec(p); g:=g^.next;
 end;

{собственно присваиваю символьной переменной, находящейся по этому адресу значение x,
то бишь значение символа под номером q}
g^.a:=x;          
end;


Опять же, все просто... ;)

Автор: QDe5n1K 25.11.2004 19:43

Нет, не просто ;)


while assigned(p) do
begin
write(p^.a,' ');
p:=p^.next;
end;


-при попытке все вывести на экран все буквы выводятся в боратном порядке smile.gif

И еще: как сортировать буквы из этого списка по алфавитному порядку? Я пытаюсь так:

while assigned(p^.next) do begin
pp:=p;
while assigned(p^.next) do begin
ppp:=p^.next;
if ppp^.a>pp^.a then
  begin
       tmp:=ppp^.a;
       ppp^.a:=pp^.a;
       pp^.a:=tmp;
  end;
ppp:=ppp^.next;
end;
pp:=pp^.next;
end;
{здесь я заканчиваю сортировать и пробую вывести результат}
while assigned(p^.next) do
write(p^.a,' ');

В итоге у меня все зацикливается и не реагирует ни на что smile.gif Блин, может у меня повторяется все одна и та же ошибка? Подскажите, плз!

Автор: volvo 25.11.2004 20:21

QDe5n1K

Цитата
при попытке все вывести на экран все буквы выводятся в боратном порядке

Трудно что-либо сказать без полного кода (что такое assigned, допустим, понятно, а вот как именно заполняется список?)

Автор: QDe5n1K 25.11.2004 20:44

Вот код процедуры open


procedure view_list(p:plist; a:char);
begin
while p<>nil do
begin
write(p^.a , ' ');
p:=p^.next;
end;
end;

procedure open(var p:plist;var a:char);
var filex:text;
   s:string;
   pp:plist;
begin
firstofall;
nameoffile(s);
assign(filex,s);
reset(filex);
while not eof(filex) do
   begin
   new(pp);
   pp^.next:=p;
   read(filex, pp^.a);
   p:=pp;
   end;
pp:=p;
view_list(pp,a);
readkey;
end;

А в файл все буквы записываются как и положено, слева направо... открывал блокнотом и проверял smile.gif

Автор: Werwolf86 26.11.2004 2:49

Цитата(volvo @ 24.11.04 17:44)
{берем новый элемент из "кучи"}
    pp^.next:=p; {его "следующему" значению }
    readln(filex, pp^.a); {записываем в новый элемент данные}]

из какой кучи?))) вообще то это называеться выделением памяти под новый элемент))...

Автор: volvo 26.11.2004 2:56

Werwolf86
А откуда, интересно, выделяется память? (Heap - это все-таки "куча")

Автор: QDe5n1K 26.11.2004 3:42

Куча, куча, volvo прав ;)... и все же, что же не так в моей программе, помогите найти ошибку smile.gif

Автор: volvo 26.11.2004 4:04

QDe5n1K
А ошибка в том, что ты добавляешь новый элемент в начало списка, а нужно добавлять в конец...


{добавление в начало списка выглядит так:}
{пусть p - начало списка}
new(pp);
pp^.a := ...;
pp^.next := p;
p := pp;

{добавление в конец списка выглядит так:}
{пусть p - начало списка, at_end - конец списка}
new(pp);
pp^.a := ...;
pp^.next := nil;
if p = nil then p := pp else at_end^.next := pp;
at_end := pp;

Что это значит? Это значит, нужно ввести дополнительную переменную "at_end" того же типа, как и "p", которая всегда будет указывать на конец списка, и добавлять данные по приведенной выше схеме в конец списка... :yes:

(Примечание: перед началом работы со списком p = nil и at_end = nil)

Автор: QDe5n1K 26.11.2004 6:13

Хм... ну тогда по идее можно ограничится вариантом без дополнительных указателей:


p:=nil;
while not eof(filex) do
   begin
   new(p);
   read(filex, p^.a);
   write(p^.a,' ');
   p^.next:=nil;
   p:=p^.next;
   end;
   p^.next:=nil;
end;
Разве не так?
И еще, а какже вторая часть моего вопроса? smile.gif
Нужно отсортировать буквы в списке в алфавитном порядке:

procedure sort(var p:plist);
var tmp:char;
   flag:boolean;
   a:char;
begin
repeat
flag:=false;
while assigned(p^.next) do
begin
    if p^.a>p^.next^.a then
       begin
       tmp:=p^.a;
       p^.a:=p^.next^.a;
       p^.next^.a:=tmp;
       flag:=true;
       end;
end;
until flag=true;
while assigned(p) do
write(p^.a,' ');
readln;
end;

По идее должно работать, но не работает sad.gif
P.S. Volvo, если я тебя уж больно загрузил, то извини, больше не буду smile.gif только подскажи в посл раз плиииз smile.gif

Автор: volvo 26.11.2004 13:26

QDe5n1K


p:=nil;
while not eof(filex) do
  begin
  new(p);
  read(filex, p^.a);
  write(p^.a,' ');

  p^.next:=nil; p:=p^.next;
{ После выполнения этих 2-х команд p ВСЕГДА будет равняться nil,
т.е. данные не будут связаны одно с другим... }

  end;
  p^.next:=nil; { ... и эта команда будет ошибочной }
end;

А вообще, могу тебе посоветовать такой способ работы со списком, как написать программу на листе бумаги, а потом рядом с ней попытаться нарисовать список, вручную проходя по строчкам программы (и выполняя те же действия, которые должна выполнять программа)... Вот это выявляет все ошибки (проверено неоднократно) :yes:

Автор: QDe5n1K 29.11.2004 19:23

Вот блин, опять проблема... которая кажется мне неразрешимой smile.gif))


procedure open(var p:plist);
var filex:text;
   s:string;
   flagg,x:shortint;
   last,first,pp:plist;
   a:char;
begin
{...............}
assign(filex,s);
reset(filex);
last:=nil;
while not eof(filex) do
   begin
   new(p);
   p:=last;
   read(filex, p^.a);
   last:=p^.next;
   end;
{*}
while p<>nil do  begin
write(p^.a,' ');
p:=p^.next;       end;
end;

Так вот, проблема заключается в том, что данные из файла я считать то считал, но КАК СДЕЛАТЬ, ЧТОБЫ ЭТИ ДАННЫЕ ВЫВОДИЛИСЬ? Я так понял, что нужно p присвоить p начальное... но как это сделать, в толк никак не возьму smile.gif А так, вроде во всем разобрался...
И пожалуйста, не подумайте, что я прикалываюсь smile.gif)))

Автор: Бродяжник 29.11.2004 20:30

Цитата
данные из файла я считать то считал
...нет, батенька, не считали! Смотрим код:
last:=nil;
while not eof(filex) do
  begin
  new(p);
  p:=last;
  read(filex, p^.a);
  last:=p^.next;
  end;
Итак: last:=nil;

Сие означает, что мы указатель на "хвост" списка делаем пустым. К чему бы? Ну да ладно. Единственный вопрос, который возникает, это где же у нашего списка "голова"? Впрочем, идем дальше.
new(p); - выделяем память под элемент списка.
p:=last; - и тут же ее теряем. Ведь, как мы помним, last у нас = nil. А теперь и p тоже nil.
read(filex, p^.a); - считываем из файла значения для элемента списка. Куда считываем??? Ведь p у нас nil!
last:=p^.next; - это было бы не лишено смысла, если бы опять таки p не было nil.
Я бы сделал нечто наподобие следующего:
Код

procedure open(var p:plist);
var filex:text;
  s:string;
  iterator:plist;
begin
{...............}
assign(filex,s);
reset(filex);

new(p);  {выделяем память под первый элемент списка}

iterator:=p; {ставим указатель на "голову"}

while not eof(filex) do
  begin
  read(filex,iterator^.a); {считываем очередное значение из файла}

  if not eof(filex) then {если это значение не последнее}
     begin                    {то выделяем память под следующий элемент}
        new(iterator^.next);
        iterator := iterator^.next;   {сдвигаем указатель}
     end;
  end;

  iterator^.next := nil; {все; дальше элементов нет.}
{теперь у нас p указывает на первый, а iterator - на последний элемент}
Мне самому не нравится то, что в цикле чтения оказалось сразу две проверки на EoF, но на скорую руку я ничего лучше не придумал.
Цитата
Сделал, что мог, и пусть, кто может, сделает лучше!

Автор: GoodWind 29.11.2004 20:42

так... зачем тебе last и pp ?
(прости, нет времени просматривать предыдущие посты)
так я делал сегодня:

function load:plist;
var begin,temp:plist; f:text;
begin
 assign(f,'file.dat');
 reset(f);
 new(temp);
 begin:=temp;
   while not eof(filex) do
     begin
       read(f,temp^.a);
       temp^.next:=new(plist);
    end;
 temp^.nex:=nil; {в целесообразности не уверен}
 load:=begin;
end;

procedure show_list(as: Plist);
begin
 while as^.next<>nil do
   begin
     writeln(as^.a);
     as:=as^.next;
   end;
end;
набирал тут, так что могут быть ошибки....
скорее всего они есть.... Паса ща нету, проверить не могу...
перезайду, исправлю если неправильно..

Автор: volvo 29.11.2004 20:45

Бродяжник
Ну, если уже вводить дополнительную переменную, которая укажет на конец списка, то я бы делал вот так:


procedure open(var p:plist);
var
 pp:plist;
 iterator: plist;
begin

p := nil; { пишем в пустой список }
while not eof(filex) do
 begin
   new(pp);
   read(filex, pp^.a);
   pp^.next := nil;
   if p = nil then p := pp else iterator^.next := pp;
   iterator := pp;
 end;

end;

QDe5n1K, я же этот способ описывал раньше... почему не используем?

Автор: Бродяжник 29.11.2004 21:42

volvo
Да, это лучше. :P

Автор: viagra levitra cialis which is b 31.08.2021 0:53

Lioresal Acheter En France

Автор: hydroxychloroquine cost at costc 18.09.2021 11:09

Best Place Buy Strattera Atomoxetine

Автор: prednisolone acetate ophthalmic 10.10.2021 21:46

Levitra How Long To Work

Автор: what foods to avoid when taking 8.11.2021 16:01

Prix Amoxil En Pharmacie

Автор: hydroxychloroquine for rheumatoi 4.12.2021 4:22

Buy Lipitor Online With No Prescription