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

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

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

Автор: -=Считывающий=- 19.10.2006 20:45

Доброе время суток!
Вот значится какая проблемма, есть файл следующе структуры:
<Фамилия_1> <Ответ1> <Ответ2>
...
<Фамилия_n> <Ответ1> <Ответ2>
, причем у каждого человека по два РАЗНЫХ ответа.

Нужно найти все разные ответы, и найти кол-во повторов каждого из них.

В принципе уже понял как что делать, но, неповерите, запоролся в самом начале)))
Решил создать массив строк, чисто для удобства и вот тут я появилась проблемма.
Происходит следующее, в процессе формирования - все ок, но как только процедура по созданию массива заканчивает работу, весь массив смещается на одну позицию вниз, т.е. 1 становится 2, 2 -3 и т.д.

Вот код и файл БД)), подскажите, в чем проблемма?




Прикрепленные файлы
Прикрепленный файл  L_2_41.PAS ( 5.02 килобайт ) Кол-во скачиваний: 196
Прикрепленный файл  1.TXT ( 61 байт ) Кол-во скачиваний: 166

Автор: volvo 19.10.2006 21:06

Ты приведи свою процедуру для создания "массива" (может, все-таки, списка?) в ЧИСТОМ виде, без наворотов интерфейса... А то смотреть на АЛГОРИТМ невозможно, все твои "рюшечки" его закрывают... А толку от них? Если программа НЕ РАБОТАЕТ.

Приводи программу, которая реализует логику, и не вылетает в Segmentation Fault после того, как был выбран первый пункт меню, и нажат Enter (таким образом, я физически не могу перейти ко второму пункту, и посмотреть, что же программа печатает, компиляцию и тестирование в Turbo Pascal не предлагать, если FPC показывает мне ошибки и недочеты, то TP просто "замалчивает" их, и веры программе еще меньше)

Автор: мисс_граффити 19.10.2006 21:44

а ради чего нужно затевать извращения с текстовым файлом?

Автор: -=Считывающий=- 19.10.2006 22:33

Чисто сама процедура:


Прикрепленные файлы
Прикрепленный файл  01.PAS ( 311 байт ) Кол-во скачиваний: 149

Автор: -=Считывающий=- 19.10.2006 22:44

убито почти все оформление


Прикрепленные файлы
Прикрепленный файл  002.PAS ( 3.68 килобайт ) Кол-во скачиваний: 173

Автор: мисс_граффити 19.10.2006 23:31

На вопросы принципиально не отвечаешь?...
И цикл while тоже принципиально не используешь?

Автор: -=Считывающий=- 19.10.2006 23:38

работа с файлом - требование заказчика) а вот на счет while...

Автор: мисс_граффити 20.10.2006 0:06

именно с текстовым? типизированные он не любит?

Автор: -=Считывающий=- 21.10.2006 11:20

Так, вобщемто я забил на масссив. Вот примерный скелет решения через список. Умоляю, посмотрите!... там трабл с пролистыванием второго. Оч надо...


Прикрепленные файлы
Прикрепленный файл  002.PAS ( 5.1 килобайт ) Кол-во скачиваний: 165

Автор: мисс_граффити 21.10.2006 15:53

С какой стати мы должны помогать и вникать в твой код, если ты не удосуживаешься даже отвечать на поставленные вопросы, напрямую относящиеся к делу?

Автор: -=Считывающий=- 21.10.2006 17:28

Извиняюсь. Честно. Просто все в торопях делаю. На счет текстового файла. Да) Т.е. работать надо именно с тектовым файлом.

И еще раз прошу прощения...

Автор: -=Считывающий=- 21.10.2006 23:37

Ну правда, умоляю, помогиите разобраться... если бы мне нужно было просто сделать, я бы так и сказал. А хочется понять... по этому и выклыдываю всякую дребедень. ПЛЗ, помогите....

Автор: мисс_граффити 22.10.2006 0:29

если читать задачу, то вообще пофиг, какие студенты дали тот или иной ответ говорили.
чтобы добиться того, что написано, нужно:
0. создаем список ответов. запись будет содержать 3 поля - информационное, куда записывается "булка", "сдоба" и т.д.; количество таких ответов; указатель на след. эл-т.
1. читаем строку из файла
2. "выдергиваем" из нее первый ответ.
3. проходим по списку. если такой ответ уже был, прибавляем единичку к количеству, если не было - добавляем новый элемент.
4. "выдергиваем" второй ответ.
5. идем на п.2

и так, пока не кончатся строки.
чем тебя не устраивает этот алгоритм?

Автор: -=Считывающий=- 22.10.2006 0:54

кстати мысль... спасибки! попробую, как зделаю, выложу)

Автор: -=Считывающий=- 22.10.2006 15:13

Только одно но:

3. проходим по списку. если такой ответ уже был, прибавляем единичку к количеству, если не было - добавляем новый элемент.

Нет. Если ответ уникален - тогда новый элемент списка, если нет, то просто ничего не делать, т.е. пропустить его. А вот там где мы создали новый элемент, там поставить доп. процедуру для анализирования всего файла на предмет повторов в нем ответа схожего с полем нашего элемента.

Вроде так... хотя могу ошибаться.... Ваше мнение?)

Автор: мисс_граффити 22.10.2006 15:38

делай как хочешь.
твоя программа.

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

Автор: -=Считывающий=- 22.10.2006 16:14

Просто вопрос в том, как будет работать.... Если предположить:
3. проходим по списку. если такой ответ уже был, прибавляем единичку к количеству, если не было - добавляем новый элемент, то имея файл

Иванов 1 2
Петров 3 1
Сидоров 2 1

Получаем:
Сначала, по алгоритму создаемтся новый эл. с полями 1,1(ну, предположим, что число повторов по умолчанию 1);
Затем создается 2,1; 3,1, а вот потом, к какому числу повторов будет прибывлена едицица? Получается надо тогда дописывать поиск элемента списка с заданным информационным поме 1 равным 1 и во второе(количество) делать плюс один? или как?... Вот поэтому и спрашиваю.... а на счет файла - да)... это весело)

Автор: мисс_граффити 22.10.2006 16:22

смотри, что мы должны делать:
1. По моей задумке.
Читаем ответ из файла. Сравниваем его с первым значением из списка. Совпало? +1 во второе поле. Не совпало? Переходим на следующий элемент. Совпало?... Список кончился (т.е. в поле Next нуль-указатель), а элемент так и не нашелся? Добавляем новый такой элемент. Читаем следующий ответ из файла.
Для реализации потребуется:
цикл while, выход из которого происходит в случае окончания списка или нахождения элемента; рабочий указатель на текущий элемент, указатель на начало списка.

2. что предлагаешь ты.
Читаем ответ. Проходим список в поиске его. Если не нашли, добавляем и ищем по всему файлу вниз. Доходим до конца файла. Закрываем файл. Открываем файл. Перематываем до исследованного элемента. Идем вниз. Читаем следующий элемент. Опять изучаем список....

Что больше нравится - то и реализуй.
Я не вижу смысла в таких сложностях - ходить по списку ведь приходится не меньше...

Автор: volvo 22.10.2006 16:26

Цитата
Получается надо тогда дописывать поиск элемента списка с заданным информационным поме 1 равным 1
Зачем? Ты же все равно проходишь по списку... Вот нашел ты ответ. Он уже есть в списке... Прибавь 1 к счетчику, и все... Зачем еще один поиск элемента?

Автор: -=Считывающий=- 22.10.2006 16:35

Аааааа!!!! Вот теперь я понял, ссори, тупой)) give_rose.gif
Попробую)

Автор: -=Считывающий=- 22.10.2006 17:39

так... получилось что-то такое) ну и (кто бы сомневался)))) что-то не так) Не посмотрите?....Прикрепленный файл  TEST02.PAS ( 4.24 килобайт ) Кол-во скачиваний: 344

Автор: мисс_граффити 22.10.2006 17:46

у меня не выводит вообще ничего при выборе 2 пункта (1 работает, вроде).
так и должно быть?

Автор: -=Считывающий=- 22.10.2006 17:47

вот в том-то и дело)) не посмотришь что не так?...плз give_rose.gif

Автор: volvo 22.10.2006 18:27

Во-первых, ты неправильно делаешь проверку... Я бы делал так:

Procedure Proverka(buf:string;var flag:boolean);
Var bufHead:NSl;
Begin
bufHead:=Head;
flag:=false;
While bufHead<>nil do
Begin
If bufHead^.Sname=buf
Then
begin
flag:=true;
end;
bufHead:=bufHead^.Next; { <--- Это надо делать ВСЕГДА, иначе очень возможно зацикливание }
end;
End;
(зачем менять глобальную переменную дважды, если можно один раз поменять локальную?)

Второе - печать списка, совершенно аналогично, не меняй глобальные переменные (ими вообще лучше не пользоваться, но это - отдельная тема для разговора):
Procedure PrintSl(Sl:NSl);
Var
i, n:integer;
p: nsl;
Begin
p:=Sl;
While (p<>nil) do
Begin
writeln(p^.Sname,' ',p^.Kol);
p:=p^.Next;
end;
end;
(естественно, что вызывать печать списка в главном Case придется по-другому:
2: PrintSl(Head);
)

Ну, и самое главное, ты неправильно конструируешь список... Прежде всего, при инициализации нового элемента, его Next нужно об-Nil-ить:
Procedure NewSl(var Sl:NSl);
Begin
New(Sl);
sl^.next := nil; { <--- Вот тут !!! }
If Head=nil then
Begin
Head:=Sl;
{ Tail:=Sl; } { <--- Это - одинаковое для обеих веток действие, выносим ПОД If }
end
else
begin
Tail^.Next:=Sl;
{ Tail:=Sl; } { <--- Это - одинаковое для обеих веток действие, выносим ПОД If }
end;

Tail := Sl;
End;
Ну, и основная ошибка - ты зачем меняешь Head^? Не проще ли сделать так:

       If flag=false then
Begin
NewSl(Sl);
sl^.Sname:=St_Otv1; { Зачем-то ты же инициализировал Sl, правда? }
sl^.Kol:=1;
end
?

Автор: -=Считывающий=- 22.10.2006 22:18

Спасибо огромное! Понял, исправлю! Вы очень помогли, если бы не Вы, незнаю чтобы я делал, правда! Спасибо! give_rose.gif

Автор: мисс_граффити 22.10.2006 23:12

Цитата(volvo @ 22.10.2006 15:27) *
       If flag=false then 

ты чего? blink.gif

Автор: volvo 22.10.2006 23:25

Цитата
ты чего? blink.gif
Это не я, я ж не перерабатывал программу полностью (если бы с нуля делать, я бы сделал совершенно по-другому), как у автора было - так и оставил. На правильность ЭТО не влияет smile.gif

Автор: мисс_граффити 23.10.2006 16:59

Цитата(volvo @ 22.10.2006 20:25) *

Это не я, я ж не перерабатывал программу полностью (если бы с нуля делать, я бы сделал совершенно по-другому), как у автора было - так и оставил. На правильность ЭТО не влияет smile.gif

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

Автор: volvo 23.10.2006 17:37

На уровне кодирования. В частности, я бы не стал никогда отдельно (в процедуре) выделять место под элемент в списке, и ВНЕ процедуры заполнять этот элемент данными... Я бы передавал в процедуру сами данные и на месте сразу "выделил память/заполнил ее"

Опять же глобальные переменные - больной вопрос. Я бы не использовал...

Автор: мисс_граффити 23.10.2006 17:51

ясно smile.gif
я думала, какие-то оптимизации именно по алгоритму...