3

我不明白为什么这段代码不能正常工作:

program selection;
var 
    n : integer;
begin
    readln(n);
    if (n in [100..1000]) then writeln('Selected!');
    readln;
end.

这对我来说适用于 1 到 233 之间的值,如果我输入 233 或更多,writeln.. 不会被执行。这很奇怪。我也尝试过其他值,结果或多或少相同,唯一不同的是它失败的值。

4

2 回答 2

13

Delphi 集最多只能达到 255 个;最大值为 1000 的集合不起作用。我对您编译的代码感到有些惊讶。

当截断为 8 位时,值 1000 为 232,这解释了为什么大于该值的值会失败。

相反,您可以使用该InRange功能;它像集合构造函数一样使用封闭范围。

if InRange(n, 100, 1000) then ...

您还可以使用普通的旧不等式运算符来测试该值是否在给定范围内:

if (100 <= n) and (n <= 1000) then ...

最后,您可以使用case语句。案例语句选择器不是集合,因此它们不受与集合相同的规则的约束。

case n of
  100..1000: begin ... end;
end;

缺点是当只有一个 case 分支时,它看起来有点笨拙。

于 2013-03-28T12:52:01.410 回答
7

Rob 解释了为什么你不能使用 Delphi 集来满足你的需要。我还要强调 aset是一种非常重量级的类型,用于存储相当于间隔的内容。一旦认识到这一点,就可以使用类似InRange在间隔上运行的函数。

作为一个有趣的练习,您可以编写一个表示区间的简单记录。然后您可以使用运算符重载来实现一个in将测试区间包含的运算符。这使您可以使用可读的符号,并自然存储一段时间。当然,元素大小没有限制。

这是一个简单的演示:

{$APPTYPE CONSOLE}

type
  TInterval = record
  public
    Low: Integer;
    High: Integer;
  public
    class operator In(const Value: Integer; 
      const Interval: TInterval): Boolean; inline;
  end;

class operator TInterval.In(const Value: Integer; 
   const Interval: TInterval): Boolean;
begin
  Result := (Value>=Interval.Low) and (Value<=Interval.High);
  // or implement with a call to Math.InRange()
end;

function Interval(Low, High: Integer): TInterval; inline;
begin
  Result.Low := Low;
  Result.High := High;
end;

begin
  Writeln(25 in Interval(10, 100));
  Writeln(125 in Interval(10, 100));
  Writeln(2500 in Interval(1000, 10000));
  Writeln(12500 in Interval(1000, 10000));
  Readln;
end.
于 2013-03-28T14:43:23.827 回答