delphi 如何确定数组中最常出现的数字?

hi3rlvi2  于 2022-11-04  发布在  其他
关注(0)|答案(4)|浏览(283)

在我用100个介于1和11之间的随机值填充数组后,如何确定哪个值出现得最多?

raogr8fs

raogr8fs1#

下面是一个示例代码:

procedure TForm1.Button1Click(Sender: TObject);

  function Calculate: Integer;
  var
    Numbers: array [1..100] of Byte;
    Counts: array [1..11] of Byte;
    I: Byte;
  begin
    // Fill the array with random numbers
    for I := Low(Numbers) to High(Numbers) do
      Numbers[I] := Random(11) + 1;
    // Count the occurencies
    ZeroMemory(@Counts, SizeOf(Counts));
    for I := Low(Numbers) to High(Numbers) do
      Inc(Counts[Numbers[I]]);
    // Identify the maximum
    Result := Low(Counts);
    for I := Low(Counts) + 1 to High(Counts) do
      if Counts[I] > Counts[Result] then
        Result := I;
  end;

begin
  ShowMessage(Calculate.ToString);
end;
xqkwcwgp

xqkwcwgp2#

这是一个简单的问题[...]
是的
但我在网上找不到任何直接的答案。
你不应该在网上寻找解决方案;相反,你应该开始考虑如何设计一个能够解决问题的算法。2为此,你可能需要纸和笔。
首先,我们需要一些数据:

const
  ListLength = 100;
  MinValue = 1;
  MaxValue = 11;

function MakeRandomList: TArray<Integer>;
begin
  SetLength(Result, ListLength);
  for var i := 0 to High(Result) do
    Result[i] := MinValue + Random(MaxValue - MinValue + 1);
end;

MakeRandomList函数用于创建一个动态整数数组。该数组包含ListLength = 100整数,范围从MinValue = 1MaxValue = 11(根据需要)。
现在,给定这样一个整数列表,

var L := MakeRandomList;

我们如何找到出现频率最高的值?
好吧,如果我们不用计算机,只用纸和笔来解决这个问题,我们可能会计算每个不同值(1,2,...,11)在列表中出现的次数,不是吗?
那么我们只需要找到频率最高的值。
例如,给定数据

2, 5, 1, 10, 1, 5, 2, 7, 8, 5

我们会数出频率

X   Freq
2   2
5   3
1   2
10  1
7   1
8   1

然后,我们从上到下阅读表格,找出出现频率最高的那一行,不断跟踪当前的赢家。
现在我们知道了 * 如何 * 解决这个问题,编写一段代码来执行这个算法就很简单了:

procedure FindMostFrequentValue(const AList: TArray<Integer>);
type
  TValueAndFreq = record
    Value: Integer;
    Freq: Integer;
  end;
var
  Frequencies: TArray<TValueAndFreq>;
begin

  if Length(AList) = 0 then
    raise Exception.Create('List is empty.');

  SetLength(Frequencies, MaxValue - MinValue + 1);

  // Step 0: Label the frequency list items

  for var i := 0 to High(Frequencies) do
    Frequencies[i].Value := i + MinValue;

  // Step 1: Obtain the frequencies

  for var i := 0 to High(AList) do
  begin
    if not InRange(AList[i], MinValue, MaxValue) then
      raise Exception.CreateFmt('Value out of range: %d', [AList[i]]);
    Inc(Frequencies[AList[i] - MinValue].Freq);
  end;

  // Step 2: Find the winner

  var Winner: TValueAndFreq;
  Winner.Value := 0;
  Winner.Freq := 0;

  for var i := 0 to High(Frequencies) do
    if Frequencies[i].Freq > Winner.Freq then
      Winner := Frequencies[i];

  ShowMessageFmt('The most frequent value is %d with a count of %d.',
    [Winner.Value, Winner.Freq]);

end;
9nvpjoqh

9nvpjoqh3#

Delphi 有一个TDictionary类,你可以用它来实现一个频率Map,例如:
第一个

e0uiprwp

e0uiprwp4#

我还在学习中,因此我觉得我处理这个问题的方式可能更接近于我本来会做的:

procedure TForm1.GetMostOccuring;
var
  arrNumbers : array[1..100] of Integer;
  iNumberWithMost : Integer;
  iNewAmount, iMostAmount : Integer;
  I, J : Integer;
begin
  for I := 1 to 100 do
    arrNumbers[I] := Random(10) + 1;

  iMostAmount := 0;

  for I := 1 to 10 do
  begin
    iNewAmount := 0;

    for J := 1 to 100 do
      if I = arrNumbers[J] then
        inc(iNewAmount);

    if iNewAmount > iMostAmount then
    begin
      iMostAmount := iNewAmount;
      iNumberWithMost := I;
    end;
  end;

  ShowMessage(IntToStr(iNumberWithMost));
end;

我希望这不是完全没用,它只是对一个简单问题的简单回答。

相关问题