Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Выбрать минимальное значение по двум полям


Автор: kami 5.1.2012, 23:45
Доброго времени суток, дамы и господа!
Столкнулся с такой проблемой:

Код

class Item
    Value1: double; // только положительные, диапазон от 0 до почти бесконечности
    Value2: integer; // только положительные, диапазон от 0 до ~ 300
   ...
end;

ItemArray: array of Item; // количество элементов - не более 100. Пойдет и TList, если есть разница, но, имхо, несущественно.


Собственно, что требуется:
выбрать элемент массива, содержащий минимальные значения обоих параметров. При этом в выбранном элементе каждый из параметров может быть не самым минимальным, минимум должна представлять их "сумма" (само собой - не в буквальном смысле). Больший приоритет имеет Value1.
Поискать не вышло, гугл выкидывает всякие задачки на сортировку и min-max одномерных массивов.

Пока додумался только сделать сортировку по возрастанию сперва по второму параметру а потом по первому и взять нулевой элемент после сортировки, но это не совсем то.
Пример того, что нужно (цифры взяты методом трех "П"):
Код

Value1    Value2 // исходные значения
   1          6
   5          1
   2          4
   2          2

После обеих сортировок будет:
   1          6  // по моему "методу" будет выбран этот элемент
   2          2  // а нужно - вот этот. Наиболее близко к минимуму по Value1, и не сильно большое Value2.
   2          4
   5          1


Как что-то подобное можно реализовать?

Автор: Keeper89 6.1.2012, 03:01
Я запутался с суммой - что значит не в буквальном смысле?

Пока вижу стандартную задачу на минимум, если честно.

Автор: Qu1nt 6.1.2012, 03:19
Первое, что пришло в голову — Теорема Пифагора smile
Код

uses
  Generics.Collections, Generics.Defaults, Math;

type
  TItem = class
  private
    FValue1: Double;
    FValue2: Integer;
    FDistance: Double;
  public
    constructor Create(Value1: Double; Value2: Integer);
    function ToString: String; override;
    property Value1: Double read FValue1;
    property Distance: Double read FDistance;
  end;

constructor TItem.Create;
begin
  FValue1 := Value1;
  FValue2 := Value2;
  FDistance := Sqrt(Sqr(FValue1) + Sqr(FValue2));
end;

function TItem.ToString;
begin
  Result := Format('%f %d', [FValue1, FValue2]);
end;

procedure TMainForm.FormCreate(Sender: TObject);
var
  List: TList<TItem>;
begin
  List := TList<TItem>.Create(TComparer<TItem>.Construct(
    function(const Left, Right: TItem): Integer
    begin
      Result := CompareValue(Left.Distance, Right.Distance);
      if Result = 0 then
        Result := CompareValue(Left.Value1, Right.Value1);
    end));
  try
    List.AddRange([
      TItem.Create(1, 6),
      TItem.Create(5, 1),
      TItem.Create(2, 4),
      TItem.Create(2, 2)]);

    List.Sort;

    Self.Caption := List.First.ToString;
  finally
    List.Free;
  end;
end;

Автор: kami 6.1.2012, 10:10
Цитата(Keeper89 @  6.1.2012,  03:01 Найти цитируемый пост)
что значит не в буквальном смысле?

Именно это и значит, что просто сложить их не получится, уже думал над этим. Value1 может быть достаточно большим, чтобы сумма его с Value2 не имела значительного эффекта.


Цитата(Qu1nt @  6.1.2012,  03:19 Найти цитируемый пост)
Первое, что пришло в голову — Теорема Пифагора

Класс!!! Имхо, то что нужно.
Спасибо!

Автор: Keeper89 6.1.2012, 12:23
Все-таки не вижу необходимости делать сортировку.

Автор: kami 6.1.2012, 17:16
Цитата(Keeper89 @  6.1.2012,  12:23 Найти цитируемый пост)
Все-таки не вижу необходимости делать сортировку.

А я ее и не буду делать, в предложенном Qu1nt варианте это не особо нужно. smile
Кстати, 
Цитата(Keeper89 @  6.1.2012,  03:01 Найти цитируемый пост)
Пока вижу стандартную задачу на минимум, если честно

Задача, конечно, стандартная. Весь вопрос был в том, как скомбинировать два поля для вычисления этого минимума...

Автор: Keeper89 6.1.2012, 18:31
Понял =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)