Справка по программированию на Паскале - PullRequest
2 голосов
/ 01 марта 2010

Я опубликовал это ранее, и оно было закрыто, потому что я не показал свою попытку его кодирования, поэтому вот вопрос:

SECTIONS
$160 = section 1
$220 = section 2
$280 = section 3
$350 = section 4
$425 = section 5

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

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

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

Вот моя попытка: * Обратите внимание, что это запрограммировано на Паскале, и мне нужна помощь, чтобы исправить и закончить его. Пожалуйста, помогите и еще раз спасибо.

program Masqueraders;

uses
  WinCrt;  { Allows Writeln, Readln, cursor movement, etc. }

const
   MAX = 5; {this determine the amount of masquarader entered}
Type
  listname = Array[1..MAX] of string;
  listsect = Array[1..MAX] of string;
var
 names : listname;
 sections : listsect;
 i, amount, TotalMas, TotalAmt, c1, c2, c3, c4, c5, amt1, amt2, amt3, amt4, amt5 :     integer;

begin

 amount := 1;
 while amount <> 0 do
 begin

      i := i + 1;
      readln(names[i]);
      readln(amount);

      if(amount = 160) then
      begin

                c1 := c1 + 1;  {Count the number of persons for section 1}
                amt1 := amt1 + amount; {accumulate the amount for section 1}
                sections[i] := 'Section 1';
      end;

      if(amount = 220) then
      begin

                c2 := c2 + 1;  {Count the number of persons for section 1}
                amt2 := amt2 + amount; {accumulate the amount for section 1}
                sections[i] := 'Section 2';
      end; {end the IF for section 2}

      if(amount = 280) then
      begin

                c3 := c3 + 1;  {Count the number of persons for section 1}
                amt3 := amt3 + amount; {accumulate the amount for section 1}
                sections[i] := 'Section 3';
      end; {end the IF for section 3}

      if(amount = 350) then
      begin

               c4 := c4 + 1;
               amt4 := amt4 + amount;
               sections[i] := 'Section4';
      end; {end If for section 4}

      if (amount = 425) then
      begin

               c5 := c5 + 1;
               amt5 := amt5 + amount;
               sections[i] := 'Section5';


  end;{end the while loop}

  TotalMas := c1 + c2 + c3;
  TotalAmt := amt1 + amt2 + amt3;


  writeln('Name                    Section');  {Heading for the output}
  for i := 1 to MAX do
  begin

       write(names[i]);
       writeln('                    ',sections[i]);

  end;


  writeln('Section 1: ');
  write('Masquader: ', c1);
  write('Amount: ', amt1);



  writeln('Total Number of Masquarader: ', TotalMas);
  writeln('Total Amount Paid by masquarader: ', TotalAmt);

конец; конец.

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

Имя Джон Деньги = 160 Раздел 1

Имя Кита Деньги = 220 Раздел Джон

Вот что я хочу:

Имя Джон Деньги = 160 Раздел1

Имя Кита Деньги = 220 Раздел2

Ответы [ 4 ]

4 голосов
/ 01 марта 2010

Я не очень знаком с Pascal, поэтому не могу вам сказать как исправить это, но я замечаю одну проблему: ваш код нарушает правило "СУХОЙ": не повторять Сам. Код внутри каждого блока if amt = xxx выглядит практически одинаково, так есть ли способ, которым вы можете написать этот код один раз, а затем каждый раз вызывать код с различными параметрами? Что-то, чтобы вы не переписывали один и тот же код пять раз.

3 голосов
/ 02 марта 2010

Вот проблемы, которые я вижу:

  1. В требованиях указано «неопределенное количество маскарадеров», но вы установили максимум на 5. Вы не можете сохранить список имен в массиве фиксированного размера, если возможно будет более 5 маскарадеров. , Таким образом, приложение может привести к сбою или повреждению памяти (в зависимости от используемой вами версии Pascal), когда пользователь входит в 6-й маскарадер. Если вам разрешено печатать Имя и Раздел маскарадера сразу после его ввода, вы должны напечатать это сразу после того, как пользователь введет Имя и Сумму (а не после ввода в цикле). Однако, если требуется распечатать список имен и разделов после всех вводимых данных, необходимо сохранить раздел Имя + в структуре данных переменной длины, такой как связанный список, или даже в более простой строке.

  2. Переменные от c1 до c5 и от amt1 до amt5 лучше объявить как два массива (c и amt) из 1..MAX вместо 10 переменных. Когда пользователь вводит сумму, используйте ее для определения номера раздела, который затем можно использовать в качестве индекса для массивов c и amt.

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

  4. Массив разделов не нужен. Все, что он содержит, - это заголовок раздела, который не нужно рассчитывать или хранить.

  5. Если вы используете цикл повтора / до вместо цикла while, это позволит избежать слегка запутанной инициализации "amount: = 1" в верхней части для входа в цикл while. Повтор / до будет до тех пор, пока сумма = 0.

  6. TotalMas только добавляет c1 к c3 (как насчет c4 и c5)?

  7. TotalAmt только добавляет amt1 к amt3 (как насчет amt4 и amt5)?

  8. Цикл for для печати имен и разделов полностью неверен, см. Пункты 1 и 4.

Надеюсь, это поможет, и дайте мне знать, если вам нужны разъяснения по любым вопросам.

3 голосов
/ 02 марта 2010

Вот несколько советов по улучшению вашего кода:

  • Как вы думаете, может ли быть способ напечатать «Section {i}» в вашем последнем цикле, не просматривая его с использованием section [i], тем самым полностью исключая необходимость в массиве? *

  • Как вы могли бы построить это так, чтобы добавление раздела 6 не потребовало изменений в вашем коде?

  • listname и listsect очень похожи, какие изменения в вашем коде вы могли бы сделать, чтобы исключить необходимость иметь два идентичных определения?

  • Что произойдет, если пользователь введет 0 для суммы, когда он в третий раз получает запрос?

Примечание: один из этих советов должен указывать вам непосредственно на источник вашей проблемы.

0 голосов
/ 02 марта 2010

Мои жалобы с этим кодом:

1) Имена переменных воняют. Практически все они слишком короткие, они не сообщают, что они делают.

2) Здесь используется неправильная структура управления циклом.

3) Я вижу практически идентичный код, повторенный 5 раз. Это просто вызов массивов.

4) Комментарии объясняют, что вы делаете, а не то, почему вы это делаете. Половина из них практически абсолютно бесполезна, если вы собираетесь комментировать end , вы должны просто прокомментировать его с указанием того, к чему это конец. конец; // если я вижу только один комментарий, который даже пытается объяснить, почему, и вы ошибаетесь, когда смешиваете людей с разделами.

5) Ваш массив разделов не выполняет ничего полезного. Присвоения значений всегда фиксированы, и поэтому нет никакой причины их хранить вообще - если вам нужны ярлыки, вы можете создать их во время печати. ​​

6) Вы предполагаете, что будет только 5 человек. Это не дано в проблеме - есть 5 разделов .

...