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

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

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

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

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

Приводи программу, которая реализует логику, и не вылетает в Segmentation Fault после того, как был выбран первый пункт меню, и нажат Enter (таким образом, я физически не могу перейти ко второму пункту, и посмотреть, что же программа печатает, компиляцию и тестирование в Turbo Pascal не предлагать, если FPC показывает мне ошибки и недочеты, то TP просто "замалчивает" их, и веры программе еще меньше)
мисс_граффити
а ради чего нужно затевать извращения с текстовым файлом?
-=Считывающий=-
Чисто сама процедура:
-=Считывающий=-
убито почти все оформление
мисс_граффити
На вопросы принципиально не отвечаешь?...
И цикл while тоже принципиально не используешь?
-=Считывающий=-
работа с файлом - требование заказчика) а вот на счет while...
мисс_граффити
именно с текстовым? типизированные он не любит?
-=Считывающий=-
Так, вобщемто я забил на масссив. Вот примерный скелет решения через список. Умоляю, посмотрите!... там трабл с пролистыванием второго. Оч надо...
мисс_граффити
С какой стати мы должны помогать и вникать в твой код, если ты не удосуживаешься даже отвечать на поставленные вопросы, напрямую относящиеся к делу?
-=Считывающий=-
Извиняюсь. Честно. Просто все в торопях делаю. На счет текстового файла. Да) Т.е. работать надо именно с тектовым файлом.

И еще раз прошу прощения...
-=Считывающий=-
Ну правда, умоляю, помогиите разобраться... если бы мне нужно было просто сделать, я бы так и сказал. А хочется понять... по этому и выклыдываю всякую дребедень. ПЛЗ, помогите....
мисс_граффити
если читать задачу, то вообще пофиг, какие студенты дали тот или иной ответ говорили.
чтобы добиться того, что написано, нужно:
0. создаем список ответов. запись будет содержать 3 поля - информационное, куда записывается "булка", "сдоба" и т.д.; количество таких ответов; указатель на след. эл-т.
1. читаем строку из файла
2. "выдергиваем" из нее первый ответ.
3. проходим по списку. если такой ответ уже был, прибавляем единичку к количеству, если не было - добавляем новый элемент.
4. "выдергиваем" второй ответ.
5. идем на п.2

и так, пока не кончатся строки.
чем тебя не устраивает этот алгоритм?
-=Считывающий=-
кстати мысль... спасибки! попробую, как зделаю, выложу)
-=Считывающий=-
Только одно но:

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

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

Вроде так... хотя могу ошибаться.... Ваше мнение?)
мисс_граффити
делай как хочешь.
твоя программа.

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

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

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

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

Что больше нравится - то и реализуй.
Я не вижу смысла в таких сложностях - ходить по списку ведь приходится не меньше...
volvo
Цитата
Получается надо тогда дописывать поиск элемента списка с заданным информационным поме 1 равным 1
Зачем? Ты же все равно проходишь по списку... Вот нашел ты ответ. Он уже есть в списке... Прибавь 1 к счетчику, и все... Зачем еще один поиск элемента?
-=Считывающий=-
Аааааа!!!! Вот теперь я понял, ссори, тупой)) give_rose.gif
Попробую)
-=Считывающий=-
так... получилось что-то такое) ну и (кто бы сомневался)))) что-то не так) Не посмотрите?....Нажмите для просмотра прикрепленного файла
мисс_граффити
у меня не выводит вообще ничего при выборе 2 пункта (1 работает, вроде).
так и должно быть?
-=Считывающий=-
вот в том-то и дело)) не посмотришь что не так?...плз give_rose.gif
volvo
Во-первых, ты неправильно делаешь проверку... Я бы делал так:
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
?
-=Считывающий=-
Спасибо огромное! Понял, исправлю! Вы очень помогли, если бы не Вы, незнаю чтобы я делал, правда! Спасибо! give_rose.gif
мисс_граффити
Цитата(volvo @ 22.10.2006 15:27) *
       If flag=false then 

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

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

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

Опять же глобальные переменные - больной вопрос. Я бы не использовал...
мисс_граффити
ясно smile.gif
я думала, какие-то оптимизации именно по алгоритму...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.