Даны названия N различных обществ (N заданное число), фигуристы которых участовали в соревновании. О каждом фигуристе известно: фамилия, название общества и 10 оценок за его выступление. Требуется для каждого спортивного общества определить фигуриста, показавшего наивысший результат, считая его единственным. Баллы, полученные фигуристом, подсчитываются следующим образом: максимальная и минимальная оценки отбрасываются, а из остальных формируется средняя. При вводе данных обеспечить уникальность наименований обществ и обязательную принадлежность фигуриста к одному из них.
volvo
9.12.2007 17:41
... и что? Хорошее задание, только зачем ты привел его? Чтоб тебе все сделали и выложили "на тарелочке"? Иди в Поиск, там есть задачи про хоккейные и футбольные команды, группы студентов с оценками на экзамене, разбирайся, как они сделаны, начинай делать свое задание, что будет непонятно - приходи, спрашивай...
А так просто вываливать задание безо всяких попыток решить (и показать остальным, что ты пытался, но у тебя не получилось) - это по меньшей мере обрекать тему на забвение...
npl
9.12.2007 17:48
Частично задача решена. А именно, я создаю типизированный файл, куда помещаю фамилии, названия обществ и оценки.
andriano
9.12.2007 18:28
Цитата(npl @ 9.12.2007 13:48)
Частично задача решена. А именно, я создаю типизированный файл, куда помещаю фамилии, названия обществ и оценки.
Интересно также узнать, ЗАЧЕМ ты это делаешь. По условию, вроде, этого не требуется.
npl
9.12.2007 18:38
Вот код
program obchestva_and_figuristyi; uses crt; type figurist=record fio:string[10]; obsh:string[10]; ocenka:array[1..10] of integer; end; var f:file of figurist; ftxt:text; i,cod:integer; z:figurist; st:string; max,min:integer; s,sr:real; begin clrscr; assign(ftxt,'figur1.txt'); reset(ftxt); assign(f,'figur.dat'); rewrite(f); while not eof(ftxt) do begin readln(ftxt,st); z.fio:=copy(st,1,pos(' ',st)); z.obsh:=copy(st,12,pos(' ',st)); delete(st,1,22); for i:=1 to 10 do begin val(st[1],z.ocenka[i],cod); delete(st,1,2); end; write(f,z); end; close(ftxt); close(f); reset(f); while not eof(f) do begin read(f,z); write(z.fio,' ',z.obsh,' '); for i:=1 to 10 do write(z.ocenka[i]); writeln; max:=z.ocenka[1]; for i:=2 to 10 do begin if z.ocenka[i]>max then max:=z.ocenka[i]; end; write(max,' '); min:=z.ocenka[1]; for i:=2 to 10 do begin if z.ocenka[i]<min then min:=z.ocenka[i]; end; write(min,' '); s:=0; for i:=1 to 10 do s:=s+z.ocenka[i]; write(s:2:1,' '); sr:=(s-max-min)/8; writeln(sr:2:2); end; close(f); end.
Пока я определил максимальную, минимальную оценку, отбросил их и нашёл среднюю.
Добавлено через 5 мин. Думаю, что делать дальше. Создать ещё один типизированный файл, туда поместить фамилии фигуристов, названия обществ и их средние оценки. И дальше работать с этим файлом, чтобы для каждого общества найти фигуриста с максимальным результатом.
npl
9.12.2007 21:20
Народ, откликнитесь.
andriano
9.12.2007 23:00
То, что ты сделал, возможно, подходит под определение "бессмысленная работа с типизированным файлом", но никак не "работа с текстовым файлом". Бессмысленная потому, что все эти манипуляции не нужны. Все операции целесообразно делать непосредственно в оперативной памяти, введя массив типа figurist и целую переменную, индицирующую длину заполненной части этого массива. Что же касается темы, то вероятнее всего, имеется в виду чтение и разбор входного текстового файла с фигурисами, а также вывод результата работы в текстовый же файл. Пока что на том этапе, что ты опубликовал, у тебя содержится несколько непоняток и минимум одна ошибка. Непонятки заключены в том, почему ты считаешь, что Ф.И.О. способны всегда поместиться в 10 символов, а также длниа названия спортивного общества не может превышать этой величины? Ошибка - в том, что ты перед чтением оценки зачем-то удаляешь из строки 22 симвлоа. Почему именно 22? Это такая мировая константа?
npl
9.12.2007 23:05
Цитата(andriano @ 9.12.2007 19:00)
То, что ты сделал, возможно, подходит под определение "бессмысленная работа с типизированным файлом", но никак не "работа с текстовым файлом". Бессмысленная потому, что все эти манипуляции не нужны. Все операции целесообразно делать непосредственно в оперативной памяти, введя массив типа figurist и целую переменную, индицирующую длину заполненной части этого массива. Что же касается темы, то вероятнее всего, имеется в виду чтение и разбор входного текстового файла с фигурисами, а также вывод результата работы в текстовый же файл. Пока что на том этапе, что ты опубликовал, у тебя содержится несколько непоняток и минимум одна ошибка. Непонятки заключены в том, почему ты считаешь, что Ф.И.О. способны всегда поместиться в 10 символов, а также длниа названия спортивного общества не может превышать этой величины? Ошибка - в том, что ты перед чтением оценки зачем-то удаляешь из строки 22 симвлоа. Почему именно 22? Это такая мировая константа?
Результат не нужно выводить в текстовый файл. Ф.И.О. в 10 символов, потому что в текстовом файле, который есть Ф.И.О. не превышает 10 символов. А дальше идёт название общества. Она тоже не больше 10. 10+пробел+10+пробел=22. Минимальные, максимальные он находит правильно. Среднее тоже.
Добавлено через 4 мин. Лучше подскажите, как из средних для каждого общества найти фигуриста с максиальным результатом.
andriano
9.12.2007 23:20
Если проверка задания будет выполнена по уму, то файл с фигуристами тебе будет предложен другой. Есть ли уверенность, что твоя программа с ним справится? "Не больше" и "равно" - далеко не одно и то же. Если, скажем, фамилия - Иванов, а название общества - Динамо, то есть ли уверенность, что удалять все равно надо 22 символа? Тот факт, что при существующем файле максимальное и минимальное находит правильно, еще не говорит о том, что так будет всегда.
Ты считал средние не для каждого общества, а для каждого фигуриста. Теперь надо соотнести фигуристов с конкретными обществами и для каждого общества найти максимальное среди средних для входящих в него фигуристов.
npl
9.12.2007 23:22
Если ФИО меньше 10, то там оставшееся место заполнено пробелом.
Ты считал средние не для каждого общества, а для каждого фигуриста. Теперь надо соотнести фигуристов с конкретными обществами и для каждого общества найти максимальное среди средних для входящих в него фигуристов.
И как это сделать?
andriano
9.12.2007 23:29
А есть ли описание формата файла? Не может оказаться, что в другом файле будет заполняться пробелами до 12-го символа, а в третьем - все разной длины и с единственным пробелом-разделителем? Для того, чтобы решать задачу, надо точно знать условие. В текстовых файлах нет определенной структуры, поэтому обычно нет никакого выравнивания проблами по длине, а при необходимости используются разделители: пробел, символ табуляции, запятая, конец строки... Ты сам составлял файл или его тебе дал преподаватель?
npl
9.12.2007 23:32
Я сам составлял файл. Задачу надо решать для конкретного своего файла.
Добавлено через 13 мин. andriano, может уже предложите конкретные решения, а не пустые слова?
andriano
10.12.2007 0:09
Цитата(npl @ 9.12.2007 19:32)
Я сам составлял файл. Задачу надо решать для конкретного своего файла.
Я бы на месте преподавателя захотел посмотреть, как программа будет работать на других файлах. (наверное, из меня вышел бы очень вредный преп.
Цитата
Добавлено через 13 мин. andriano, может уже предложите конкретные решения, а не пустые слова?
Вообще-то я даю именно КОНКРЕТНЫЕ советы по решению. Если подробнее, то я могу порекомендовать следующий алгоритм разбора строки: 1. Удаляем пробелы в начале. 2. Находим позицию разделителя L. 3. Если L = 0, выводим сообщение об ошибке, иначе продолжаем работу. 4. Копируем в поле имени L-1 символов. 5. Удаляем L символов в начале строки. 6. Удаляем пробелы в начале. 7. Находим позицию разделителя L. 8. Если L = 0, выводим сообщение об ошибке, иначе продолжаем работу. 9. Копируем в поле названия команды L-1 символов. 10. Удаляем L символов в начале строки. 11. Цикл длиной 9. 12. Удаляем пробелы в начале. 13. Находим позицию разделителя L. 14. Если L = 0, выводим сообщение об ошибке, иначе продолжаем работу. 15. Копируем во временную строку L-1 символов. 16. Пытаемся преобразовать эту строку в число. 17. Если преобразование не удалось - выводим сообщение об ошибке, иначе - продолжаем работу. 18. Удаляем L символов в начале строки. 19. Конец цикла. 20. Удаляем пробелы в начале. 21. Пытаемся преобразовать оставшуюся часть строки в число. 22. Если преобразование не удалось - выводим сообщение об ошибке, иначе - продолжаем работу.
В качестве ваианта: 11. Дописываем разделитель в конец строки. 11а. Цикл длиной 10. строки 20-22 - не нужны.
npl
10.12.2007 0:12
Да забудьте про преобразование. Оставлю так, как есть. Как найти фигуриста с максимальным результатом для каждого общества?
andriano
10.12.2007 0:15
Самый простой способ - перебором.
PS. А алгоритм разбора строки я бы порекомендовал подправить.
npl
10.12.2007 1:36
Не получается найти максимальный элемент. Когда находится максимальный среди 10 оценок, там всё просто. А как сделать среди средних? Дайте конкретный пример.
andriano
10.12.2007 2:38
Коль скоро для каждого фигуриста все равно вычисляется средняя оценка, то имеет смысл предусмотреть в структуре поле для ее хранения. Ну и потом, естественно, перебирать эти поля в поисках максимума.
npl
10.12.2007 2:49
Цитата(andriano @ 9.12.2007 22:38)
Коль скоро для каждого фигуриста все равно вычисляется средняя оценка, то имеет смысл предусмотреть в структуре поле для ее хранения. Ну и потом, естественно, перебирать эти поля в поисках максимума.
И как их перебирать. У меня не работает. Приведите свой код.
andriano
11.12.2007 0:57
А ты не заметил, что твоя программа не совсем соответствует условию задачи? В условии требуется анализировать общества (и именно их количество указано), а у тебя предусмотрен тип данных для описания фигуриста и нет типа данных для общества.
npl
11.12.2007 1:09
Цитата(andriano @ 10.12.2007 20:57)
А ты не заметил, что твоя программа не совсем соответствует условию задачи? В условии требуется анализировать общества (и именно их количество указано), а у тебя предусмотрен тип данных для описания фигуриста и нет типа данных для общества.
Есть у меня тип данных для общества.
andriano
11.12.2007 1:32
Пальчиком ткни.
npl
11.12.2007 2:25
obsh:string[10]; вот тут, может хватить мудить, если б вы andriano знали, давно бы уже написали нужный мне код
!
За речью следи.
andriano
13.12.2007 0:46
Грубить не надо. Помочь - могу, а писать код за тебя - не буду.
Вот это называется типом данных:
type figurist=record fio:string[10]; obsh:string[10]; ocenka:array[1..10] of integer; end;
А вот это - полем в типе "figurist", имеющим тип "string[10]":
obsh:string[10];
Не следует поутать одно с другим.
Вообще-то алгоритм написания программы на каком либо языке программирования примерно такой: - решить задачу ручками, отмечая про себя, какие действия при этом происходят, - записать алгоритм действий по-русски, - переписать на нужном языке программирования.
При обработке текстовых файлов, как правило, удобно оказывается действовать в следующем порядке: - завести тип данных, хорошо описывающий входные данные, - завести тип данных, хорошо описывающий выходные данные, - считать входные данные в память, - в памяти обработать входняе данные с целью заполнить поля выходного типа.
npl
13.12.2007 3:33
"Спасибо", что не помогли, andriano. Но к счастью в этом мире есть добрые люди.
Michael_Rybak
13.12.2007 3:51
"Спасибо" andriano от тебя заслуживает как минимум за потраченное на тебя время. Смени тон.
npl
13.12.2007 3:55
Цитата(Michael_Rybak @ 12.12.2007 23:51)
"Спасибо" andriano от тебя заслуживает как минимум за потраченное на тебя время. Смени тон.
Никто не заставлял его тратить на меня время. И вовсе я не грублю. Извините, если, что-то не так сказал, но нервы перед сессией накалены до предела.
Добавлено через 15 мин. Огромное спасибо volvo!!!
Michael_Rybak
13.12.2007 4:20
Цитата
Никто не заставлял его тратить на меня время.
Аааа, т.е. когда ты задаешь вопрос, я должен не отвечать, а сначала спросить тебя, заставляешь ты меня или нет? Т.к. если я отвечу не то, что ты бы ожидал услышать, то я в ответ получу "пустые разговоры" и "мудить". Какая прелесть.
Цитата
но нервы перед сессией накалены до предела.
Сочувствую (без сарказма). И тем не менее.
npl
13.12.2007 17:11
Цитата(Michael_Rybak @ 13.12.2007 0:20)
Аааа, т.е. когда ты задаешь вопрос, я должен не отвечать, а сначала спросить тебя, заставляешь ты меня или нет? Т.к. если я отвечу не то, что ты бы ожидал услышать, то я в ответ получу "пустые разговоры" и "мудить". Какая прелесть.
Отвечать или нет - это личное дело каждого. А если уж решил ответить, то отвечать надо по существу, а не уходить от вопроса.
Lapp
13.12.2007 18:24
М
Господа, прошу прекратить перебранку. Тему закрывать не хочу, потому что она, по-видимому, еще нужна автору (если нет - скажи).
npl, прошу тебя понять, что замечания отвечавших тебе направлены на улучшение твоей программы, хотя ты этого можешь не понимать в настоящий момент.
andriano, прошу тебя быть более конкретным в ответах. Постарайся отвечать не только правильно, но и так, чтоб тебя поняли - чтобы поняли, что ты говоришь по существу.
К всем: побольше дружелюбия. А грубость прошу исключить совсем.
В дальнейшем прошу говорить только по теме Спасибо.
andriano
14.12.2007 13:40
"Пришел барин и всех рассудил." :D
[ ]
Мне кажется, вряд ли здесь кто-то не понимает по-русски. Скорее дело в другом: нужен текст на Паскале, а самому переводить с русского на Паскаль не хочтся, - пусть лучше это сделает кто-то другой!
Тем более, что исправлять явно указанный недостаток автор этой темы не захотел, решив, очевидно, что и так сойдет. Между тем программа, работающая с текстовыми файлами, должна быть нечувствительна к количеству пробелов, разделяющих слова, т.е. совершенно одинаково обрабатывать "Иванов Динамо" и " Иванов Динамо ". Приведеная же программа, очевидно, с текстовыми файлами работать не умеет, а умеет только с файлами опредедленной структуры.
Теперь по поводу задачи в целом (заодно уважаемый volvo сможет сравнить со своим вариантом).
- Предусмотреть типы данных для фигуриста (в исходном коде уже есть) и для спортивного общества (название, Ф.И.О. ОДНОГО спортсмена, его средний результат). - Описать переменную для спортсмена (уже есть), массив длины N для обществ (благо, в условии она задана. Можно потребовать, чтобы первой строкой в файле указывалось количество обществ: для учебных/олимпиадных задач - обычное дело. А можно и не требовать: вместо массива организовать список, выделяя память для каждого очередного элемента по мере их поступления) и целую переменную для длины заполненной части массива. - написать функции (декомпозиция - великая вещь!) для: а) разбора строки с заполнением полей "фигуриста": на входе - строка из файла, возвращает - подсчитанное среднее. Функция должна уметь разбирать файлы вроде:
Иванов и.И. "Спартак" 1 2 3 4 5 6 7 8 9 10 Сидоров Иван Петрович "Крылья Советов" 3, 4, 5, 5, 7, 8, 9, 10, 11, 12 Мохаммед Ибн Али ПЕру де Оннорре "ООО Челси им. Абрамовича" 2;3;4;5;6;7;8;9;10;1 Смит Джон "Определитель Матрицы" 8.0,7.0, 9, 3., 4, 1.0, 7, 5,9,2 Петров-Водкин Кузьма С. "Спартак" 3,2 1,3,2 1,3 2,1 1,1
б) поиска и добавления обществ: на входе - строка-имя общества, на выходе - номер найденного общества в массиве. Должна просматривать уже сформированную часть массива обществ, если не нашла - завести новое, обнулив все поля.
Порядок действия программы: 1. Открыть файл. 1а. При необходимости считать строку с количеством обществ и выделить память для массива. 2. Цикл до окончания файла: - читаем строку - разбираем ее - находим номер общества - если средний балл спортсмена найденного общества ниже, чем вновь считанного, заменяем все данные общества новым спортсменом 3. Закрыть файл. 4. Вывести в цикле на печать заполненный массив обществ.
Кстати, размещать в общедоступном месте (например, на форуме) програму без комментаиев - mauvais ton. Должна быть минимум одна строка коментария на 5-7 строк кода. Должны быть откомментированы все процедуры и функции: назначение и список параметров. Должны быть откомментированы все новые типы и их поля, а также глобальные переменные. Естественно, не должно быть коментариев типа: r := sqrt(x*x + y*y); {присваиваем переменной r значение sqrt(x*x + y*y)}
Malice
14.12.2007 15:27
Начнем тогда уж.. Внесу свою лепту для начала
type fig=record fio:string; obsh:string; ocenka: array[1..10] of integer; end; ... procedure parse (s:string;var f:fig); var i,n:integer; begin f.fio:=copy(s,1,pos ('"',s)-1); delete(s,1,length(f.fio)+1); f.obsh:='"'+copy(s,1,pos ('"',s)-1)+'"'; delete(s,1,length(f.obsh)-1); for i:=1 to 10 do begin while (not(s[1] in ['0'..'9'])) and (s>'') do delete (s,1,1); n:=0; while (s[1] in ['0'..'9']) and (s>'') do begin n:=n*10+ord (s[1])-$30; delete (s,1,1); end; f.ocenka[i]:=n; end; end;
andriano
14.12.2007 22:17
Цитата(Malice @ 14.12.2007 11:27)
Начнем тогда уж.. Внесу свою лепту для начала
OK. Несколько рекомендаций:
ocenka: array[1..10] of integer;
Насколько я помню, в фигурном катании оценки являются числом в общем случае нецелым. Рекомендую:
ocenka: array[1..10] of single;
procedure parse (s:string;var f:fig);
Вообще-то переменная f одна на всю программу, при этом временная и глобальная. Поэтому вряд ли имеет смысл передавать ее в качестве формального параметра. Впрочем, это дело вкуса. А еще я рекомендовал сразу подсчитать средний балл и возвращать его как значение функции.
function parse (s:string): single;
Следующую строку:
f.obsh:='"'+copy(s,1,pos ('"',s)-1)+'"';
можно немного упростить.
f.obsh:='"'+copy(s,1,pos ('"',s));
Следующий код ориентирован на целые числа, кроме того, вместо:
n:=n*10+ord (s[1])-$30;
правильнее было бы написать:
n:=n*10+ord (s[1])-ord('0');
В любом случае, рекомендую в этом месте скопировать во временную строку все символы до разделителя или конца строки, а потом преобразовать строку в число. Перед этим лучше всего сначала заменить все разделители на пробелы, а затем удалить все двойные пробелы. Ну и под конец, естественно, подсчитать средний балл.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.