在 Raku 中将数字重新排列为非英文字母顺序

Posted

技术标签:

【中文标题】在 Raku 中将数字重新排列为非英文字母顺序【英文标题】:Rearrange a number into non-English alphabetical order in Raku 【发布时间】:2020-09-13 18:29:17 【问题描述】:

我正在尝试将数字重新排列为非英文字母顺序。

my @numDE = < null eins zwei drei  vier fünf sechs sieben acht  neun >;
# english   < zero one  two  three four five six   seven  eight nine >;

my %numrank; # The lookup hash: number => its_alphabetical_order

for @numDE.sort.kv -> $k,$v %numrank%(@numDE.kv.reverse)"$v" = "$k";

my %temp; # number => reassigned order value  
%temp"$_"= %numrank"$_" for "2378".comb; # 2378 sample input
say %temp.sort(*.values); # this prints:
# (8 => 0 3 => 1 7 => 7 2 => 9) it's in order but unformatted

my %target= %temp.sort(*.values); # Attempt to print it in order
for %target.kv -> $k,$v print $k; # that prints in random order

1- 如何按顺序打印%temp 哈希?

2- (可选)有没有办法开始使用散列变量而不用my 声明它,即像在 Python 中一样?

3-(可选)我选择了查找方法来解决这个问题,结果代码看起来有点复杂。是否可以使用任何其他方法缩短解决方案?

【问题讨论】:

快速评论:它尚不可用,但正在开展工作以提供本地化排序算法(最初在模块空间中,但很可能最终在核心中)。我一直很糟糕,没有完成准备工作,但我一直说我会做一些 samcv++ 可以集成到 moarVM 中的东西。 关于主题的更多信息,关于最终分配,您将分配回一个无序的哈希。 是的。这是试图以有序的形式打印数字,但因为我在上一节上花了一个多小时,所以我筋疲力尽,想不出更好的办法。 【参考方案1】:

所以有几件事我要看看,但看起来你确实做了一些额外的步骤(在你说你已经尝试了一些不同的事情的 cmets 中,所以我想你最初并没有做很多额外的事情)。

您首先给自己提供了德国号码:

my @numDE = <null eins zwei drei vier fünf sechs sieben acht neun>;

接下来,您希望能够根据德语拼写来订购商品。我会尝试使用您已经接近的方法,但最后我会向您展示一种更简单的方法。您的下一步是有效地缓存它们的排序顺序,并将其存储到变量“numrank”中。基于@numDE.sort.kv,我们得到

my %numrank;
for @numDE.sort.kv -> $k, $v 
    %numrank$v = $k;

say %numrank;
# acht => 0, drei => 1, eins => 2, fünf => 3, neun => 4, null => 5, sechs => 6, sieben => 7, vier => 8, zwei => 9

好吧,还不错。另请注意,虽然%numrank 的输出看起来是有序的,但作为散列,它本质上是无序的。它只是碰巧按字母顺序打印键,我们的键和值在这些行上排序。现在我们只需要使用 actual 数字作为键,而不是使用德语名称。

my %numrank;
for @numDE.sort.kv -> $k, $v 
    my $id == @numDE.first: $v;
    %numrank$id = $k;

say %numrank;

糟糕,我们得到了同样的结果。这是因为.first 返回的是实际对象。对于它的索引,我们只附上:k 副词:

my %numrank;
for @numDE.sort.kv -> $k, $v 
    my $id == @numDE.first: $v, :k;
    %numrank$id = $k;

say %numrank;
# 0 => 5, 1 => 2, 2 => 9, 3 => 1, 4 => 8, 5 => 3, 6 => 6, 7 => 7, 8 => 0, 9 => 4

完美,现在我们可以看到 8 (acht) 的值为 0,因为它是第一个,而 2 (zwei) 的值是 9,因为它是最后一个。请注意,我们也可以在这里使用数组,因为我们的索引是数字(使用@numrank,然后使用@numrank[$id] = $k

现在整理一些东西。在您的代码中,您有

%temp"$_"= %numrank"$_" for "2378".comb; # 2378 sample input

这将创建一个无序散列,其中每个键的名称是一个数字,它的值是它的排名。这基本上就是我们在第一次尝试制作%numrank 时所做的。但是因为%temp 是一个哈希,如果你有任何重复的两个数字,你会失去额外的:

%temp"$_"= %numrank"$_" for "222".comb;
# 2 => 9 

相反,我认为您想创建一个允许排序的数组:

my @temp = ($_ => %numrank"$_") for "22378".comb;
# ^^ both 2s are preserved

现在您可以简单地对值进行排序:

say @temp.sort: *.values;

你可以直接循环:

for @temp.sort(*.values) 
   print .key;

更简单的方法

"2378".comb.sort:  @numDE[$^digit] 
# (8 3 7 2) # acht drei seiben zwei 

这里我们根据每个数字的德语文本形式对梳理后的数字进行排序。 @numDE 作为数字的名称,$^digit 是一个包含数字的隐式变量([ ] 自动将其强制转换为我们的数字)。如果您打算定期使用它,您实际上可以将块存储在一个变量中,如下所示:

my &sort-de = sub ($digit)  @numDE[$digit] ;
"87446229".comb.sort: &sort-de;
# (8 9 6 7 4 4 2 2)

如上所述,如果您想以其他方式对其进行样式设置,您可以直接在此执行 for 循环:

for "87446229".comb.sort(&sort-de) 
   say $_

【讨论】:

使hash 使用实际数字而不是字符来排序是正确的。更简单的方法也很好。它真正显示了语言的实用性。有用且全面。谢谢!【参考方案2】:

考虑这个问题的一种方法是作为翻译问题:我们需要将一个排序约定转换为另一个排序约定。

首先设置一对索引中的第一个,以允许在德语中按字母顺序排列数字元素(代码 sn-ps 在 Raku REPL 中执行):

> my @a = @numDE
[null eins zwei drei vier fünf sechs sieben acht neun]
> my @b = @a.pairs.sort(*.values)>>.keys.flat;
[8 3 1 5 9 0 6 7 4 2]
> say @a[@b]
(acht drei eins fünf neun null sechs sieben vier zwei)

在上面,我们展示了我们可以通过索引@b 重新排序。但是如何让@b 回到它的 原来的顺序呢?通过导出第二个“原始”索引@c

> my @c = @b.pairs.sort(*.values)>>.keys.flat;
[5 2 9 1 8 3 6 7 0 4]
> say @b[@c]
(0 1 2 3 4 5 6 7 8 9)

好的,现在我们有了解决问题所需的正确“翻译”:

> "2378".comb.trans( 0..9 => @c ).comb.sort.trans( @c => 0..9 ).trim.say
8 3 7 2

编辑——下面的第二个例子:

> "87446229".comb.trans( 0..9 => @c ).comb.sort.trans( @c => 0..9 ).trim.say
8 9 6 7 4 4 2 2

基本上我们将原始值转换为“原始索引”值、梳理、排序,最后我们将“原始索引”值反向转换为原始值。

(“8 3 7 2”是“acht drei seiben zwei”。感谢您的示例@user0721090601!)。 (注意,trim 用于清理一些格式问题)。

HTH。

【讨论】:

以上是关于在 Raku 中将数字重新排列为非英文字母顺序的主要内容,如果未能解决你的问题,请参考以下文章

按字母顺序排列字符串数组(甚至是 *ptr)

用单词和数字按字母顺序排列字符串

按字母顺序排列的字典键[重复]

使用 SQL 按字母顺序重新排列字符串中的字符 [关闭]

文件夹文件怎么排序

每日编程-20170401