Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как удалить элемент из массива в Delphi без искажения вычислений среднего значения? Решение задачи на языке Паскаль.

Delphi , Синтаксис , Массивы

 

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

Проблема удаления элементов из массива

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

Рассмотрим исходный код процедуры:

Procedure ModifierSupprimerMesure;
Var
  jour, param: Integer;
  choix: Char;
Begin
  Writeln('--- Modifier ou Supprimer une Mesure ---');
  Repeat
    Write('Entrez le numéro du jour (1 à ', Nbre_J, ') : ');
    read(jour);
  Until (jour >= 1) And (jour <= Nbre_J);
  Repeat
    Writeln('1. Pression systolique');
    Writeln('2. Pression diastolique');
    Writeln('3. Pouls');
    Write('Choisissez le paramètre à modifier/supprimer (1-3) : ');
    read(param);
  Until (param >= 1) And (param <= Max_Param);
  Repeat
    Write('Voulez-vous (M)odifier ou (S)upprimer la mesure ? (M/S) : ');
    read(choix);
    choix := Upcase(choix);
    If (choix<>'M')Or(choix<>'S') Then Writeln('choix erroné');
  Until (choix = 'M') Or (choix = 'S');

  If choix = 'M' Then
    Begin
      Write('Entrez la nouvelle valeur : ');
      read(Mesures[jour, param]);
    End
  Else
    Begin
      Mesures[jour, param] := 0;
    End;
End;

Решение 1: Использование динамических массивов

Один из способов решения проблемы - использование динамических массивов и их перераспределение при удалении элемента:

procedure DeleteArrayElement(var Arr: array of Integer; Index: Integer);
var
  i: Integer;
begin
  if (Index < Low(Arr)) or (Index > High(Arr)) then Exit;

  for i := Index to High(Arr) - 1 do
    Arr[i] := Arr[i + 1];

  SetLength(Arr, Length(Arr) - 1);
end;

Однако этот метод имеет недостатки: - Требует частого перераспределения памяти - Неэффективен для больших массивов - Усложняет код при работе с многомерными массивами

Решение 2: Использование флага для "удаленных" элементов

Более практичное решение - введение дополнительного массива флагов, указывающих на активность элементов:

var
  Mesures: array[1..MaxDays, 1..MaxParams] of Integer;
  ActiveFlags: array[1..MaxDays, 1..MaxParams] of Boolean;

procedure InitializeArrays;
var
  i, j: Integer;
begin
  for i := 1 to MaxDays do
    for j := 1 to MaxParams do
      ActiveFlags[i, j] := True;
end;

procedure DeleteMeasurement(Day, Param: Integer);
begin
  ActiveFlags[Day, Param] := False;
end;

function CalculateAverage(Param: Integer): Double;
var
  i, Count: Integer;
  Sum: Double;
begin
  Sum := 0;
  Count := 0;
  for i := 1 to MaxDays do
    if ActiveFlags[i, Param] then
    begin
      Sum := Sum + Mesures[i, Param];
      Inc(Count);
    end;
  if Count > 0 then
    Result := Sum / Count
  else
    Result := 0;
end;

Решение 3: Использование списков вместо массивов

Для более гибкой работы с данными можно использовать классы TList или TObjectList:

uses
  Classes, Contnrs;

type
  TMeasurement = class
  public
    Day: Integer;
    Systolic: Integer;
    Diastolic: Integer;
    Pulse: Integer;
    constructor Create(ADay, ASystolic, ADiastolic, APulse: Integer);
  end;

constructor TMeasurement.Create(ADay, ASystolic, ADiastolic, APulse: Integer);
begin
  inherited Create;
  Day := ADay;
  Systolic := ASystolic;
  Diastolic := ADiastolic;
  Pulse := APulse;
end;

var
  Measurements: TObjectList;

procedure InitializeMeasurements;
begin
  Measurements := TObjectList.Create(True);
  // Добавление измерений
  Measurements.Add(TMeasurement.Create(1, 120, 80, 70));
  // ...
end;

procedure DeleteMeasurement(Day: Integer);
var
  i: Integer;
begin
  for i := Measurements.Count - 1 downto 0 do
    if TMeasurement(Measurements[i]).Day = Day then
      Measurements.Delete(i);
end;

function CalculateAverage(ParamType: Integer): Double;
var
  i, Count: Integer;
  Sum: Double;
  M: TMeasurement;
begin
  Sum := 0;
  Count := 0;
  for i := 0 to Measurements.Count - 1 do
  begin
    M := TMeasurement(Measurements[i]);
    case ParamType of
      1: begin Sum := Sum + M.Systolic; Inc(Count); end;
      2: begin Sum := Sum + M.Diastolic; Inc(Count); end;
      3: begin Sum := Sum + M.Pulse; Inc(Count); end;
    end;
  end;
  if Count > 0 then
    Result := Sum / Count
  else
    Result := 0;
end;

Решение 4: Использование записей с дополнительными полями

Можно расширить структуру данных, добавив поле для отметки удаленных элементов:

type
  TMeasurement = record
    Value: Integer;
    IsActive: Boolean;
  end;

var
  Mesures: array[1..MaxDays, 1..MaxParams] of TMeasurement;

procedure DeleteMeasurement(Day, Param: Integer);
begin
  Mesures[Day, Param].IsActive := False;
end;

function CalculateAverage(Param: Integer): Double;
var
  i, Count: Integer;
  Sum: Double;
begin
  Sum := 0;
  Count := 0;
  for i := 1 to MaxDays do
    if Mesures[i, Param].IsActive then
    begin
      Sum := Sum + Mesures[i, Param].Value;
      Inc(Count);
    end;
  if Count > 0 then
    Result := Sum / Count
  else
    Result := 0;
end;

Заключение

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

  1. Использование динамических массивов с перераспределением памяти
  2. Введение флагов активности элементов
  3. Применение специализированных классов коллекций (TList, TObjectList)
  4. Расширение структуры данных дополнительными полями

Для большинства практических задач оптимальным решением будет использование подхода с флагами активности (Решение 2) или переход на списки (Решение 3), так как они обеспечивают хороший баланс между производительностью и простотой реализации.

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

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Массивы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 10:03:57/0.0038409233093262/0