德尔福 - 如何列出特定范围内的数字组合?

时间:2013-04-07 05:46:10

标签: delphi random combinations

我需要在Delphi 7中编写一个函数,列出3个整数(不重复)的所有可能组合,使用1到8的范围。例如:

123 124 125 ... 412 413 415 ... 874 875 876

此功能将用于比较目的,如果它尽可能快,那就好了。

请有人提出一个想法(如果可能的话,还有一些代码示例)?

谢谢!


嗯,这是我到目前为止所得到的。请,如果有人有任何提示,使其更好(提高性能,减少代码,......),请帮助我。再次感谢!

Function IsNumOnSet(Max, Num: Integer): Boolean;
var
  X, Y, Z: Integer;
Begin
  Result := False;
  For X := 1 to Max Do
    For Y := 1 to Max Do
      For Z := 1 to Max Do
        If (X <> Y) and (X <> Z) and (Y <> Z) Then
          If (IntToStr(X) + IntToStr(Y) + IntToStr(Z) = IntToStr(Num)) Then
          Begin
            Result := True;
            Exit;
          end;
end;

这是新的和完成的功能,肯的帮助。它可能对将来的其他人有用。谢谢!

Function IsNumOnSet(const Min, Max, Num: Integer): Boolean;
var
  X, Y, Z: Integer;
Begin
  Result := False;
  For X := Min to Max Do
    For Y := Min to Max Do
      For Z := Min to Max Do
        If (X <> Y) and (X <> Z) and (Y <> Z) Then
          If (X * 100 + Y * 10 + Z = Num) Then
          Begin
            Result := True;
            Exit;
          end;
end;

如果有人有更好的想法,请告诉我们!

2 个答案:

答案 0 :(得分:3)

你可以在没有循环的情况下解决这个问题。

提取您的号码中的三位数字,检查它们是否不同,并检查它们是否在最小,最大范围内。

uses Math;

function IsNumOnSet(min,max,num : Integer) : Boolean;
var
  d0,d1,d2 : Integer;
begin
  d0 := num mod 100;
  d1 := (num div 10) mod 10;
  d2 := num div 100;
  Result :=
    (d0 <> d1) and (d0 <> d2) and (d1 <> d2) and
    InRange(d0,min,max) and
    InRange(d1,min,max) and
    InRange(d2,min,max);
end;

答案 1 :(得分:2)

这是使用Litbox和编辑框进行的一些演示。

var
  Form1: TForm1;
  mystring                                : string;

implementation

{$R *.dfm}

procedure genstrings
          (lowchar                        : char;
           highchar                       : char;
           var outstring                  : string
          );
var
  char1                                   : char;
  char2                                   : char;
  char3                                   : char;
begin
  outstring := '';
  for char1 := lowchar to highchar do
    for char2 := lowchar to highchar do
      if char1 <> char2 then
        for char3 := lowchar to highchar do
      if (char1 <> char3) and (char2 <> char3) then
        outstring := outstring + ',' + char1 + char2 + char3;
  delete(outstring,1,1)
end;


procedure TForm1.Edit1Change(Sender: TObject);
begin with edit1 do begin
  if length(text) = 3 then
  begin
    if pos(text,mystring) > 0 then
      color := cllime
    else
      color := clred;
    if listbox1.Items.IndexOf(text) >= 0 then
      font.color := clblack
    else
      font.color := clwhite;
  end
  else
  begin
    color := claqua;
    font.Color := clfuchsia;
  end;


end;end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  genstrings('1','8',mystring);
  listbox1.Items.CommaText := mystring;
  edit1change(nil);
end;

end.

genstrings生成字符串并将它们编译成逗号分隔列表。该列表将加载到listbox1 - 两者都在创建表单。

当然,列表框可​​以直接加载,listbox.commatext用于提取完整列表。

更改编辑框后,如果其中包含的文字长度不是3个字符,则编辑框颜色将更改为蓝色的紫红色。

如果提供的字符串长度正好为3个字符,则使用两种不同的机制来验证条目。

  • 第一个验证是一个简单的POS到逗号分隔的有效子串字符串中。如果找到字符串IS,则编辑框颜色将更改为石灰,否则将更改为红色。
  • 第二个验证是尝试在列表框中找到文本(实际上是TStringList的可见形式)。如果找到,则编辑框字体颜色变为黑色,否则变为白色。

关于速度和可靠性 - 在如此小的演示中,速度实际上没什么关系。我冒昧地说POS方法比Indexof方法FWIW更快。真正的测试是真正的应用程序。字符串是否能够容纳所有目标元素?

当然,例如7,1的输入将触及POS实现中的目标,因为'7,1'是子串。 (pos... mod 5) = 1为此演示轻松治愈,但这是一个副作用。真的取决于我们不知道的 - 真正的目的是什么。例如,如果条目在编辑框中是真的,并且编辑框实际上是一个maskededit,那么可以轻松控制字符的输入。