【问题标题】:Does perl have an equivalent of +/- infinity for string comparisons?perl 是否有相当于 +/- infinity 的字符串比较?
【发布时间】:2011-04-05 14:24:54
【问题描述】:

在 perl 中,为了进行数值比较,我们将 +/- inf 作为大于/小于其他数字的数字。是否还有 gt/lt 其他字符串?

我问的原因是我想在字符串列表的末尾添加一个或另一个,以确保循环将在列表末尾之前终止。

【问题讨论】:

  • 基于该链接中的答案,我想我可以编写一个模块来重载比较函数,以便在与任何字符串进行比较时执行我想要的操作。但在实践中,我意识到我唯一要比较的是YYYYMMDD 形式的日期字符串,所以我的“无限”字符串是"99999999"。不过,我现在有点想编写模块。
  • 显然无穷大等于 99999999。谁知道呢?
  • 嗯,不。我只需要在几千年后停止使用我的脚本。这是一个千年虫。
  • 好吧,又过了一天,我终于想出了如何以 1/3 的长度和 3 倍的清晰度重写整个有问题的代码块。毫不奇怪,更新、更短、更简单的代码不需要无限字符串或任何其他愚蠢的东西。它的效率有点低(O(n^2) 而不是 O(n)),但它仍然比我启动和停止秒表的速度更快,所以谁在乎呢?

标签: perl string comparison


【解决方案1】:

没有。但是"" 将小于或等于任何其他字符串,并且 chr(~0) 重复足够多次将大于或等于该长度或更短的任何字符串。 (假设您没有通过“使用区域设置”使用基于区域设置的排序规则。)

(chr(~0) 需要no warnings 'utf8',因为它不在定义的 utf8 字符范围内。)

【讨论】:

  • @Ryan Thompson:~0 是 0 的补码,perl 将使用的最大整数(因此也是最大字符的序数值)。在 32 位 perls 上,它将是 chr(4294967295),在 64 位 perls 上,它将是 chr(18446744073709551615)。
  • 您根本不需要重复chr(~0)。因为它不是一个有效的代码点,所以它不应该出现在你程序的任何真实数据字符串中。
  • @cjm:当字符串x在程序中时,说“字符串x大于这个程序中的任何字符串”似乎有点虚伪:)
【解决方案2】:

这是一个完整的实现,它对比任何其他字符串都大的重载字符串进行了测试。它是一个非常简单的重载,为什么要使用近似值?

package String::Infinity;

use overload
    '""'  => sub {
        return "Infinity"
    },
    'cmp' => sub {
        my($left, $right, $reverse) = @_;
        return 0 if ref $right && $right->isa("String::Infinity");
        return $reverse ? -1 : 1;
    },
    fallback => 1
;

sub new {
    my $class = shift;
    return bless \Inf, $class;
}


use Test::More;

my $inf = String::Infinity->new;
is "$inf", "Infinity",  "stringification";
ok $inf eq $inf,        "equals itself"; 
ok $inf ne "foo",       "  doesn't equal anything else";
ok $inf ne "Infinity",  "  even what it stringifies to";
ok $inf gt "lfkdlk",    "  greater than";
ok !$inf lt "lkafj",    "  not less than";
is $inf cmp "lkjd", 1,  "  cmp";
is "ldfjal;kjd" cmp $inf, -1,   "  cmp reversed";

done_testing;

【讨论】:

  • 为什么?因为我(还)还不是一个 perl 专家,没有编写重载运算符的类的经验。不过,这很整洁。
【解决方案3】:

空字符串或undef 小于所有其他字符串。

没有比其他所有字符串都大的有限字符串。但是,如果您可以做出某些假设,例如循环中的所有字符串都是 ASCII 字符串,那么您可以指定一个像 "\x80"(ASCII 值 128)这样的字符串,它会大于所有字符串。

【讨论】:

  • 好吧,我可以假设我所有的字符串都是le "99999999",因为它们都是YYYYMMDD形式的日期字符串。
  • undef 用起来很傻,因为与字符串相比它会发出警告。
  • 我接受了这个答案,因为这是您在不禁用警告或自己编写的情况下能做到的最好的方法。
猜你喜欢
  • 2015-03-14
  • 2022-11-07
  • 2016-08-10
  • 1970-01-01
  • 2010-12-20
  • 2023-04-10
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
相关资源
最近更新 更多