Помощь - Поиск - Пользователи - Календарь
Полная версия: Сортировка
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Dima1111
Помогите пожалуйста разобраться, каким образом можно реализовать на TP задачу:

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

Вот образец файла:
Январь
Александров В.П. 2750.23
Иванов С.А. 2214.04
Сергеев К.А. 3122.89
Февраль
Александров В.П. 2354.33
Сергеев К.А. 2921.19
Март
Александров В.П. 2755.23
Сергеев К.А. 3122.89
Иванов С.А. 2312.34

VVVVVVVVVVVVVVVVVVVVVVVVVVV

Александров В.П.
Январь 2750.23
Февраль 2354.33
Март 2755.23
средняя зарплата =2619.93

Иванов С.А.
Январь 2214.04
Февраль нет данных
Март 2312.34
средняя зарплата =2263.19

Сергеев К.А.
Январь 3122.89
Февраль 2921.19
Март 3122.89
средняя зарплата =3055.65
RathaR
Для начала неплохо было бы уточнить входные данные: в начале неизвесно ни кол-ва сотрудников, ни кол-ва месяцев за которые нужно разсмотреть зарплаты? Порядок следования сотрудников в списке за каждый месяц также непостоянен? Во входном файле, в случае, если данные отсутствуют, также нету никакой пометки об их отсутствии, просто идёт след. сотрудник?
И вообще где у тебя возникают проблемы: в том чтобы сформировать масив записей?
volvo
Цитата
Для начала неплохо было бы уточнить входные данные: в начале неизвесно ни кол-ва сотрудников, ни кол-ва месяцев за которые нужно разсмотреть зарплаты? Порядок следования сотрудников в списке за каждый месяц также непостоянен? Во входном файле, в случае, если данные отсутствуют, также нету никакой пометки об их отсутствии, просто идёт след. сотрудник?
Ничего из вышеперечисленного не обязательно для того, чтобы иметь возможность написать программу, корректно обрабатывающую исходный файл.
RathaR
Цитата(volvo @ 12.11.2009 21:52) *

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

Так, то оно так, но зачем тратиться на изощрения, если они могут оказаться лишними... программу можна существенно упростить...
volvo
Цитата
но зачем тратиться на изощрения, если они могут оказаться лишними
Что именно? Умение программы работать с 12-ю месяцами в году может оказаться лишним? Ты предлагаешь уточнить, не достаточно ли работать только с первым полугодием? Или написание программы таким образом, чтобы для обработки бОльшего количества сотрудников достаточно было поменять одну константу (или вообще ничего не менять, при использовании других средств, как то динамические массивы или списки) - лишнее? По-моему, это как раз преимущество, а не изощрение. Так ДОЛЖНА вести себя программа.
RathaR
В основном, я о том, что , так как нету четкого порядка следования сотрудников, и их количества + возможны случаи как во входном файле за февраль, то процес чтения записи сильно усложняеться, возможно это и вызвало непонятки с програмой у автора...
Lapp
Я бы сказал так: нужны дополнительные сведения не про задачу (тут все предельно ясно), а про уровень владения (изучения) языком автором темы. Если они уже изучили динамические средства - это одно, если нет - другое.. Самый естественный способ реализации (напрашивающийся) - со списками, хотя, конечно, может быть все, что угодно. Можно даже и совсем обойтись одним string'ом для всего, если постоянно читать файл - и такая программа будет максимально независима от всяких частностей во входных данных. Кстати, не настолько уж это дольше - нормальный размер такого файла вряд ли больше дискового кэша, так что физически все будет происходить в памяти. RathaR, возьмешься написать такого уродца? )) Уверяю, это довольно забавно.. smile.gif
RathaR
Цитата(Lapp @ 13.11.2009 3:25) *

RathaR, возьмешься написать такого уродца? )) Уверяю, это довольно забавно.. smile.gif

Ну а что, уродцы тоже бывают ничего так))) я вот помниться на первой олимпиаде, в том году таким макаром решал почти аналогичную задачу в которой надо было отсортировать записи по времени в формате ЧЧ/ММ/СС + доп данные(тип счетчика електропитания и его показания), так я кроме строк тогда ничего незнал, ни записей, ни списков, вобщем, по средством десятка вложеных условных оператров решил, и нормально unsure.gif розбивал по частям, сортировал, 12 тестов из 15 прога прошла...
Хотя неспорю, это глупо, но тогда выбора небыло rolleyes.gif
Lapp
Цитата(RathaR @ 13.11.2009 3:04) *
это глупо, но тогда выбора небыло
Возможно.
Ну, что - напишешь?
RathaR
Цитата(Lapp @ 13.11.2009 4:11) *

Ну, что - напишешь?

А напишу cool.gif
RathaR
В общем объёмная програмка вышла smile.gif и глупостей в ней несчесть...
И вот еще что: писал на Turbo Delphi Explorer, так эта зараза игнорирует последние сроки в основной программе, сразу после процедуры Spisok перескакует в конец программы. Запустил в ТП - всё нормально, но прога пашет некоректно изза разных кодировок, неможет со строки правильно выделить стоимость, ибо я там ориентируюсь на '.', а при смене кодировки это уже не точка...а все русские слова в ТП переписывать заново нехотелось...
Вобщем прога поидее рабочая, но откомпилировать её полностью в TDE не удалось...

З.Ы. Старался писать так как писал бы год назад... со строками... для того чтобы она работала во входящем файле месяца должны идти по порядку, и нужно задать константу К - максимально возможное число сотрудников
{$APPTYPE CONSOLE}
program  Yrodec;
const
  digits:set of char=['0'..'9'];
  K=6;
  month:array[1..12] of string =(
    'Январь','Февраль','Март','Апрель',
    'Май','Июнь','Июль','Август',
    'Сентябрь','Октябрь','Ноябрь','Декабрь'
  );
var
  F1,F2:text;
  S:string;
  I,J:integer;
  spisok_shtata:array[1..K]of string;
  zarplata:array[1..12,1..K]of real;

function select_name(S:string):string;
var
  I:integer;
  S_:string;
  K:integer;
begin
  I:=1;
  K:=0;
  while K=0 do
  begin
    if S[I] in digits then K:=I;
    inc(I);
  end;
    S_:='';
  for I:=K-2 downto 1 do
    S_:= S[I]+S_;
  select_name:=S_;
end;

function select_cost(S:string):real;
var
  I:integer;
  cost:real;
  code:integer;
  S_:string;
begin
  for I:=1 to length(S) do
    if (S[I] in digits) or((S[I]='.')and(S[I-1] in digits)and(S[I+1] in digits))then S_:=S_+S[I];
  val(S_,cost,code);
  select_cost:=cost;
end;

function stroka_month(S:string):boolean;
var
  I:integer;
begin
  stroka_month:=false;
  for I:=1 to 12 do
    if S=month[I] then stroka_month:=true;
end;

procedure Spisok;
var
  I:integer;
  S:string;
  S_:string;
  prisutstvie:boolean;
begin
while not eof(F1) do
  begin
    readln(F1,S_);
    if not stroka_month(S_) then
      begin
      S:=select_name(S_);
      prisutstvie:=false;
      for I:=1 to K do
        if spisok_shtata[I]=S then prisutstvie:=true;
      if not prisutstvie then
        begin
        I:=1;
        while spisok_shtata[I]<>'' do
         inc(I);
         spisok_shtata[I]:=S;
        end;
      end;
  end;
end;

function nomber_of_month(S:string):integer;
var
  I:integer;
begin
  for I:=1 to 12 do
    if month[I]=S then nomber_of_month:=I;
end;

function nomber_of_sotrudnik(S:string):integer;
var
  I:integer;
begin
  for I:=1 to K do
    if select_name(S)=spisok_shtata[I] then nomber_of_sotrudnik:=I;
end;

procedure spisok_zarplat;
var
  I:integer;
  S:string;
  S_:string;
begin
  readln(F1,S);
  S_:=S;
  while not eof(F1) do
    begin
    S:=S_;
    if stroka_month(S) then
      begin
        readln(F1,S_);
        while not stroka_month(S_) do
          begin
           zarplata[nomber_of_month(S),nomber_of_sotrudnik(S_)]:=select_cost(S_);
           readln(F1,S_);
          end;
      end;
  end;
end;

procedure Obnulenie_spiska_shtata;
var
  I:integer;
begin
  for I:=1 to k do
    spisok_shtata[I]:='';
end;

procedure Obnulenie_spiska_zarplat;
var
  I:integer;
  J:integer;
begin
  for I:=1 to 12 do
    for J:=1 to K do
      zarplata[I,J]:=0;
end;

function Sr_arifm_sotrudnika(K:integer):real;
var
  I:integer;
  suma:real;
  kol_vo:real;
begin
  suma:=0;
    for I:=1 to 12 do
      begin
      suma:=suma+zarplata[I,K];
      if zarplata[I,k]<>0 then kol_vo:=kol_vo+1;
    end;
  Sr_arifm_sotrudnika:=suma/kol_vo;
end;

begin
  assign(F1,'spisok.dat');
  assign(F2,'spisok.sol');
  reset(F1);
  Obnulenie_spiska_shtata;
  Obnulenie_spiska_zarplat;
  spisok;
  close(F1);
  reset(F1);
  spisok_zarplat;
  close(F1);
  rewrite(F2);
  for I:=1 to K do
    begin
    writeln(F2,spisok_shtata[I]);
    for J:=1 to 12 do
      begin
      writeln(month[J]);
      writeln(zarplata[J,I]);
    end;
    writeln(Sr_arifm_sotrudnika(I));
  end;
  close(F2);
end.


Вход. файл
Январь
Андреев А.А. 54254
Сергеев С.С. 45468
Генадиев Г.Г. 42124
Борисов Б.Б. 154
Февраль
Андреев А.А. 4212
Сергеев С.С. 45124
Борисов Б.Б. 41211
Виталиев В.В. 1111
Март
Сергеев С.С. 45124
Борисов Б.Б. 41211
Апрель
Антонов А.А. 554
Май
Август
Сентябрь
Октябрь
Ноябрь
Декабрь

andriano
Цитата(RathaR @ 14.11.2009 21:38) *
Запустил в ТП - всё нормально, но прога пашет некоректно изза разных кодировок, неможет со строки правильно выделить стоимость, ибо я там ориентируюсь на '.', а при смене кодировки это уже не точка...
Это не кодировка. Это региональные настройки. Чтобы не иметь геморроя с насчитанными разными программами цифрами, я у себя в региональных настройках ОС меняю десятичный разделитель с запятой на точку.
Для Винды:
Contro, Panel -> Date, Time... -> Regional and Language Options -> Custimise -> Decimal Symbol
Lapp
Я извиняюсь, немного подредактировал формат в сообщении RathaR'а по-живому.. Для лучшей читаемости.
Dima1111
Спасибо большое!
Буду разбираться с кодом..
Dima1111
Цитата(RathaR @ 14.11.2009 22:38) *

Старался писать так как писал бы год назад... со строками...


PS. А как бы вы сейчас эту программу делали, c применением чего ?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.