0

在帕斯卡中,我想随机组织一个数组。因此,大多数情况下,数组应该以不同的方式组织。

考虑这个阵列设置

const
  ARRAY_ELEMENTS = 3;

SetLength(iIndex, ARRAY_ELEMENTS);

for i := Low(iIndex) to High(iIndex) do
begin
   case i of
   0: iIndex[i] := 0;
   1: iIndex[i] := 1;
   2: iIndex[i] := 2;
   end;
end; 

iIndex[]包含值 0的 怎么可能不总是在数组的第一个元素中,iIndex[]而包含值 2 的不总是数组的最后一个值,而是随机生成数组的顺序,这样数组的顺序在初始化时并不总是相同的?

4

2 回答 2

4

This code permutes an integer array, but I'm not sure if it is optimal (probably isn't).

type
  TDynIntegerArray = array of integer;

procedure PermuteArray(A: TDynIntegerArray);
var
  B: TDynIntegerArray;
  Z: TDynIntegerArray;
  π: TDynIntegerArray;
  i: Integer;
  j: Integer;
  k: Integer;
begin
  B := Copy(A);
  SetLength(Z, Length(A));
  SetLength(π, Length(A));
  for i := 0 to High(Z) do
    Z[i] := i;
  for i := 0 to High(π) do
  begin
    π[i] := RandomFrom(Z);
    for j := 0 to High(Z) do
    begin
      if Z[j] = π[i] then
      begin
        for k := j to High(Z) - 1 do
          Z[k] := Z[k+1];
        SetLength(Z, length(Z) - 1);
        break;
      end;
    end;
  end;
  for i := 0 to High(A) do
    A[i] := B[π[i]];
end;

A much faster, but less cool approach is simply to randomly swap the items, one pair at a time:

procedure FastPermuteArray(A: TDynIntegerArray);
  procedure Swap(n, m: integer);
  var
    tmp: integer;
  begin
    tmp := A[n];
    A[n] := A[m];
    A[m] := tmp;
  end;
var
  i: Integer;
begin
  for i := High(A) downto 1 do
    Swap(i, RandomRange(0, i));
end;
于 2013-03-10T16:26:58.510 回答
0

尝试这样的事情:

uses
  System.Generics.Collections;

const
  ARRAY_ELEMENTS = 3;
var
  iArray: array of Integer;
  iIndex: TList<Integer>;
  I, j: Integer;
begin
  Randomize;

  SetLength(iArray, ARRAY_ELEMENTS);

  iIndex := TList<Integer>.Create;
  try
    iIndex.Count := ARRAY_ELEMENTS;
    for i := 0 to Pred(ARRAY_ELEMENTS) do
      iIndex[i] := i;

    for i := Low(iArray) to High(iArray) do
    begin
      j := Random(iIndex.Count);
      iArray[iIndex[j]] := i;
      iIndex.Delete(j);
    end;
  finally
    iIndex.Free;
  end;
end;

如果您的 Delphi 版本中没有TList<T>可用的,您可以使用普通的TList代替:

uses
  Classes;

const
  ARRAY_ELEMENTS = 3;
var
  iArray: array of Integer;
  iIndex: TList;
  I, j: Integer;
begin
  Randomize;

  SetLength(iArray, ARRAY_ELEMENTS);

  iIndex := TList.Create;
  try
    iIndex.Count := ARRAY_ELEMENTS;
    for i := 0 to Pred(ARRAY_ELEMENTS) do
      iIndex[i] := Pointer(I);

    for i := Low(iArray) to High(iArray) do
    begin
      j := Random(iIndex.Count);
      iArray[Integer(iIndex[j])] := i;
      iIndex.Delete(j);
    end;
  finally
    iIndex.Free;
  end;
end;
于 2013-03-10T19:41:53.113 回答