-1

我这里有一个大问题,甚至不知道如何开始......

简而言之,我需要知道一个数字是否在随机组合的一组结果中......

让我更好地解释一下:我用 3 个从 1 到 8 的整数字符创建了一个随机“数字”,如下所示:

procedure TForm1.btn1Click(Sender: TObject);
var
  cTmp: Char;
  sTmp: String[3];
begin
  sTmp := '';
  While (Length(sTmp) < 3) Do
  Begin
    Randomize;
    cTmp := IntToStr(Random(7) + 1)[1];
    If (Pos(cTmp, sTmp) = 0) Then
      sTmp := sTmp + cTmp;
  end;
  edt1.Text := sTmp;
end;

现在我需要知道其他一些随机数,比如“324”(示例),是否在该随机组合的结果集中。

请问,有人可以帮忙吗?获得解决此问题的方程式的链接就足够了...


好的,让我尝试添加一些有用的信息:

请先检查此链接https://en.wikipedia.org/wiki/Combination

一旦我在编辑框中得到用户输入的一些数字,我需要检查它是否在这个随机组合的集合中:S = (1..8) 和 k = 3

棘手,嗯?


这是我得到的。也许它对将来的某人有用。感谢所有试图提供帮助的人!

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;
4

4 回答 4

1

您想测试某物是否是组合。为此,您需要验证假定的组合是否满足以下条件:

  1. 每个元素都在范围 1..N 和
  2. 没有元素出现超过一次。

所以,像这样实现它。

  • 声明一个计数数组,比如数组 [1..N] of Integer。如果 N 在运行时变化,您将需要一个动态数组。
  • 将数组的所有成员初始化为零。
  • 循环遍历假定组合的每个元素。检查元素是否在 1..N 范围内。并增加该元素的计数。
  • 如果任何元素的计数大于 1,则这不是有效的组合。

现在您可以通过用布尔数组替换整数数组来简化,但这应该是不言而喻的。

于 2013-04-06T23:22:49.213 回答
1

你有你的发电机。建立价值后,请执行以下操作

function isValidCode( Digits : Array of Char;  Value : String ) : Boolean;
var 
    nI : Integer;
begin
       for nI := 0 to High(Digits) do
       begin
             result := Pos(Digits[nI], Value ) > 0;
             if not result then break;
       end;
end;

像这样打电话...

 isValidCode(["3","2","4"], RandomValue);

注意:它仅因为您有唯一的数字而起作用,数字 3 在您的最终数字中只有一次。对于更通用的东西,您必须调整此功能。(测试 "3","3","2" 会返回 true 但它会是 false !)

更新:我不喜欢嵌套循环^^。这是一个返回整数的第 n 位的函数。如果数字不存在,它将返回 -1。:

 function TForm1.getDigits(value : integer; ndigits : Integer ) : Integer;
 var
    base : Integer;
 begin
       base := Round(IntPower( 10, ndigits-1 ));
       result := Trunc( value /  BASE ) mod 10;
 end;

nDigits 是从 1 开始从右到左的数字。它将返回数字的值。

GetDigits( 234, 1) returns 4
GetDigits( 234, 2) returns 3
GetDigits( 234, 3) returns 2.
GetDigits( 234, 4) returns 0.

现在最后一个函数检查一个值是否是一个好的组合,指定你正在寻找的 maxdigits :

function isValidCombination( value : integer; MinVal, MaxVal : Integer; MaxDigits : Integer ) :  Boolean;
var
   Buff : Array[0..9] of Integer;
   nI, digit: Integer;
 begin
   ZeroMemory( @Buff, 10*4);

   // Store the count of digits for
   for nI := 1 to MaxDigits do
   begin
      digit := getDigits(value, nI);
      Buff[digit] :=  Buff[digit] + 1;
   end;

   // Check if the value is more than the number of digits.
   if Value >= Round(IntPower( 10, MaxDigits )) then
   begin
     result := False;
     exit;
   end;

   // Check if the value has less than MaxDigits. 
   if Value < Round(IntPower( 10, MaxDigits-1 )) then
   begin
      result := False;
      exit;
   end;


  result := true;
  for nI := 0 to 9 do
  begin
     // Exit if more than One occurence of digit.
     result := Buff[nI] < 2 ;
     if not result then break;

     // Check if digit is present and valid.
     result := (Buff[nI] = 0) or InRange( nI, MinVal, MaxVal );
     if not result then break;
  end;

end;
于 2013-04-06T13:23:51.903 回答
0

问题对我来说似乎并不太模糊,也许说得不好。

据我了解,您想检查一个字符串是否在一组随机生成的字符中。

这是最快的工作方式,保留所有字母的排序数组以及每个字母的次数。

从目标字符串中减去每个字母如果排序后的 int 数组中的任何值低于 0,则意味着无法从这些字符中生成字符串。

我让它只适用于不区分大小写的字符串,但它可以很容易地适用于任何字符串,方法是使字母数组长度为 255 个字符,而不是从 A 开始。

这将不允许您像其他示例一样使用两次字符,因此 'boom' 不在 'b' 'o' 'm' 中

希望这对您有所帮助。

function TForm1.isWordInArray(word: string; arr: array of Char):Boolean;
 var
   alphabetCount: array[0..25] of Integer;
   i, baseval, position : Integer;
   s: String;
   c: Char;
begin
  for i := 0  to 25 do alphabetCount[i] := 0;  // init alphabet
  s := UpperCase(word); // make string uppercase
  baseval := Ord('A'); // count A as the 0th letter
  for i := 0 to Length(arr)-1 do begin // disect array and build alhabet
    c := UpCase(arr[i]); // get current letter
    inc(alphabetCount[(Ord(c)-baseval)]); // add 1 to the letter count for that letter
  end;
  for i := 1 to Length(s) do begin // disect string
    c := s[i]; // get current letter
    position := (Ord(c)-baseval);
    if(alphabetCount[position]>0) then // if there is still latters of that kind left
      dec(alphabetCount[position]) // delete 1 to the letter count for that letter
    else begin // letternot there!, exit with a negative result
      Result := False;
      Exit;
    end;
  end;
  Result := True; // all tests where passed, the string is in the array
end;

像这样实现:

if isWordInArray('Delphi',['d','l','e','P','i','h']) then Caption := 'Yup' else Caption := 'Nope';  //yup
if isWordInArray('boom',['b','o','m']) then Caption := 'Yup' else Caption := 'Nope';  //nope, a char can only be used once

德尔福摇滚!

于 2013-04-06T18:27:35.693 回答
-1
begin
  Randomize; //only need to execute this once.
  sTmp := '';
  While (Length(sTmp) < 3) Do
  Begin
    cTmp := IntToStr(Random(7) + 1)[1]; // RANDOM(7) produces # from 0..6
                                        // so result will be '1'..'7', not '8'
                                        // Alternative: clmp := chr(48 + random(8));
    If (Pos(cTmp, sTmp) = 0) Then
      sTmp := sTmp + cTmp;
    IF SLMP = '324' THEN
      DOSOMETHING; // don't know what you actually want to do
                   // Perhaps SET SLMP=''; to make sure '324'
                   // isn't generated?
  end;
  edt1.Text := sTmp;
end;
于 2013-04-06T11:42:13.880 回答