Помощь - Поиск - Пользователи - Календарь
Полная версия: Задача на списки.
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
QDe5n1K
Люди помогите!!! Плз... Задача звучит так:
"ВВодится некоторая последовательность букв русского алфавита и записывается в памяти в виде линейного списка. Определить упорядочена ли последовательность по алфавиту( если нет, то упорядочить), заменить выбранную K-ую букву на Q-ю, поменять местами первую и последнюю буквы...
Люди, пожалуйста, подскажите как это делать и приведите примеры кусочков кода (полный мне не нужен, хочу сам разобраться, но для этого нужно небольшое ускорение) Пожалуйста, подскажите что и как...
QDe5n1K
Почитал, многое понял...
Но тогда подскажите, в чем может быть ошибка в этой процедуре:
Код

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
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
Ладно, вот еще 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
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
Нет, не просто ;)

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
QDe5n1K
Цитата
при попытке все вывести на экран все буквы выводятся в боратном порядке

Трудно что-либо сказать без полного кода (что такое assigned, допустим, понятно, а вот как именно заполняется список?)
QDe5n1K
Вот код процедуры 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
Цитата(volvo @ 24.11.04 17:44)
{берем новый элемент из "кучи"}
    pp^.next:=p; {его "следующему" значению }
    readln(filex, pp^.a); {записываем в новый элемент данные}]

из какой кучи?))) вообще то это называеться выделением памяти под новый элемент))...
volvo
Werwolf86
А откуда, интересно, выделяется память? (Heap - это все-таки "куча")
QDe5n1K
Куча, куча, volvo прав ;)... и все же, что же не так в моей программе, помогите найти ошибку smile.gif
volvo
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
Хм... ну тогда по идее можно ограничится вариантом без дополнительных указателей:

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
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
Вот блин, опять проблема... которая кажется мне неразрешимой 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)))
Бродяжник
Цитата
данные из файла я считать то считал
...нет, батенька, не считали! Смотрим код:
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
так... зачем тебе 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
Бродяжник
Ну, если уже вводить дополнительную переменную, которая укажет на конец списка, то я бы делал вот так:

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, я же этот способ описывал раньше... почему не используем?
Бродяжник
volvo
Да, это лучше. :P
viagra levitra cialis which is b
Lioresal Acheter En France
hydroxychloroquine cost at costc
Best Place Buy Strattera Atomoxetine
prednisolone acetate ophthalmic
Levitra How Long To Work
what foods to avoid when taking
Prix Amoxil En Pharmacie
hydroxychloroquine for rheumatoi
Buy Lipitor Online With No Prescription
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.