Delphi中数组的幂集

Delphi中数组的幂集,delphi,set,combinations,Delphi,Set,Combinations,我正在尝试编写一个函数,该函数将在输入上获取一个数组并返回数组数组,其中包含输入数组的所有可能子集(没有空元素的幂集)。例如,对于输入:[1,2,3]结果将是[1]、[2]、[3]、[1,2]、[1,3]、[2,3]、[1,2,3] 此函数在python中完成以下工作: def list_powerset(lst): result = [[]] for x in lst: result += [subset + [x] for subset in result]

我正在尝试编写一个函数,该函数将在输入上获取一个数组并返回数组数组,其中包含输入数组的所有可能子集(没有空元素的幂集)。例如,对于输入:
[1,2,3]
结果将是
[1]、[2]、[3]、[1,2]、[1,3]、[2,3]、[1,2,3]

此函数在python中完成以下工作:

def list_powerset(lst):
    result = [[]]
    for x in lst:
        result += [subset + [x] for subset in result]
    result.pop(0)
    return result
但我正在寻找它在Delphi中的实现。这是可以通过这种方式实现的,还是我应该寻找其他方法?

键入
type
  TIdArray = array of Integer;
  TPowerSet = array of TIdArray;

function PowerSet(Ids: TIdArray): TPowerSet;
// Implementation loosely based on the explanation on
// http://www.mathsisfun.com/sets/power-set.html
var
  TotalCombinations: Integer;
  TotalItems: Integer;
  Combination: Integer;
  SourceItem: Integer;
  ResultItem: Integer;
  Bit, Bits: Integer;
begin
  TotalItems := Length(Ids);

  // Total number of combination for array of n items = 2 ^ n.
  TotalCombinations := 1 shl TotalItems;

  SetLength(Result, TotalCombinations);

  for Combination := 0 to TotalCombinations - 1 do
  begin
    // The Combination variable contains a bitmask that tells us which items
    // to take from the array to construct the current combination.
    // Disadvantage is that because of this method, the input array may contain
    // at most 32 items.

    // Count the number of bits set in Combination. This is the number of items
    // we need to allocate for this combination.
    Bits := 0;
    for Bit := 0 to TotalItems - 1 do
      if Combination and (1 shl Bit) <> 0 then
        Inc(Bits);

    // Allocate the items.
    SetLength(Result[Combination], Bits);

    // Copy the right items to the current result item.
    ResultItem := 0;

    for SourceItem := 0 to TotalItems - 1 do
      if Combination and (1 shl SourceItem) <> 0 then
      begin
        Result[Combination][ResultItem] := Ids[SourceItem];
        Inc(ResultItem);
      end;
  end;

end;
TIdArray=整数数组; TPowerSet=TIdArray的数组; 功能电源集(ID:TIdArray):TPowerSet; //实现松散地基于对 // http://www.mathsisfun.com/sets/power-set.html 变量 总组合:整数; TotalItems:整数; 组合:整数; SourceItem:整数; 结果m:整数; 位,位:整数; 开始 TotalItems:=长度(ID); //n项数组的组合总数=2^n。 总组合:=1个shl总项目; 设置长度(结果、总组合); 对于组合:=0到TotalCombinations-1 do 开始 //组合变量包含一个位掩码,告诉我们哪些项 //从数组中提取以构造当前组合。 //缺点是由于这种方法,输入数组可能包含 //最多32项。 //计算组合中设置的位数。这是项目数 //我们需要为这种组合进行分配。 位:=0; 对于位:=0到TotalItems-1 do 如果组合和(1 shl位)为0,则 公司(Bits); //分配项目。 设置长度(结果[组合],位); //将正确的项复制到当前结果项。 结果m:=0; 对于SourceItem:=0到TotalItems-1 do 如果组合和(1 shl SourceItem)为0,则 开始 结果[Combination][ResultItem]:=Ids[SourceItem]; 公司(ResultItem); 结束; 结束; 结束;
我的另一个答案是我不久前在Delphi 2007中需要时创建的一段代码。要使其更通用,可以使用泛型。我以前没有使用过泛型,但它似乎是这样工作的。我必须承认我必须检查语法。如果有更简单的方法,我希望其他人可以发布

事实上,除了输入参数的名称之外,代码实际上没有改变。(耶,仿制药!)

类型
TGenericArray=T的数组;
TGenericPowerSet=T的数组的数组;
TPowerSet=class(TObject)
公众的
类函数Get(a:TGenericArray):TGenericPowerSet;
结束;
类函数TPowerSet.Get(a:TGenericArray):TGenericPowerSet;
变量
总组合:整数;
TotalItems:整数;
组合:整数;
SourceItem:整数;
结果包括:整数;
位,位:整数;
开始
总计项目:=长度(a);
//n项数组的组合总数=2^n。
总组合:=1个shl总项目;
设置长度(结果、总组合);
对于组合:=0到TotalCombinations-1 do
开始
//组合变量包含一个位掩码,告诉我们哪些项
//从数组中提取以构造当前组合。
//缺点是由于这种方法,输入数组可能包含
//最多32项。
//计算组合中设置的位数。这是项目数
//我们需要为这种组合进行分配。
位:=0;
对于位:=0到TotalItems-1 do
如果组合和(1 shl位)为0,则
公司(Bits);
//分配项目。
设置长度(结果[组合],位);
//将正确的项复制到当前结果项。
结果包括:=0;
对于SourceItem:=0到TotalItems-1 do
如果组合和(1 shl SourceItem)为0,则
开始
结果[Combination][ResultItemIncluded]:=a[SourceItem];
公司(结果包括在内);
结束;
结束;
结束;
然后像这样使用:

var
  p: TPowerSet<String>;
  a: TGenericArray<String>;
  r: TGenericPowerSet<String>;
begin
  SetLength(a, 2);
  a[0] := 'aaa';
  a[1] := 'bbb';
  r := p.Get(a);

  ShowMessage(IntToStr(Length(r)));
  ShowMessage(r[1][0]);
var
p:TPowerSet;
a:TGenericArray;
r:TGenericPowerSet;
开始
设定长度(a,2);
a[0]:=“aaa”;
a[1]:='bbb';
r:=p.Get(a);
ShowMessage(IntToStr(长度(r));
ShowMessage(r[1][0]);

这样做当然是可能的(但在Delphi中代码可能不会那么简短)。我在这里的回答应该会有所帮助:我尝试了一下这个方法,经过一些修改后,它就成功了!谢谢,你是最好的。TotalCombinations:=2 shl(TotalItems-1);应为TotalCompositions:=1 shl TotalItems@DavidHeffernan得出了同样的结果,但更符合逻辑。换了。
var
  p: TPowerSet<String>;
  a: TGenericArray<String>;
  r: TGenericPowerSet<String>;
begin
  SetLength(a, 2);
  a[0] := 'aaa';
  a[1] := 'bbb';
  r := p.Get(a);

  ShowMessage(IntToStr(Length(r)));
  ShowMessage(r[1][0]);