2

我正在尝试在 D 中编写一些非常简单的代码,但是我在使用其中一个标准库模板函数(特别是nextPermutationfrom std.algorithm)时遇到了一些问题。

我要做的关键是创建泛数字的所有排列(即,包括所有值 1 到 9 的数字恰好一次)。

为此,我做了以下工作:

import std.algorithm;
import std.conv;

int[] pandigitals()
{
    char[] initial = "123456789".dup;
    auto pan = [to!int(initial)];
    while(nextPermutation!(initial)) {
       pan ~= to!int(initial);
    }
    return pan;
}

这给了我错误:

错误:无法解析 nextPermutation 的类型!(初始)

我还尝试明确设置类型:

while(nextPermutation!("a<b", char[])(initial))

但是,这会给出一个错误,指出它无法匹配模板:

错误:模板实例 std.algorithm.nextPermutation!("a < b", char[]) 与模板声明不匹配 nextPermutation(alias less = "a < b", BidirectionalRange)(ref BidirectionalRange range) if (isBidirectionalRange!BidirectionalRange && hasSwappableElements!BidirectionalRange)

调用的正确形式是什么?

4

1 回答 1

5

好吧,您的第一个问题是您initial作为模板参数而不是函数参数传递。!()用于模板参数。所以,而不是

while(nextPermutation!(initial))

你需要做

while(nextPermutation(initial)) {

现在,这仍然会给你一个错误。

q.d(10): Error: template std.algorithm.nextPermutation cannot deduce function from argument types !()(char[]), candidates are:
/usr/include/D/phobos/std/algorithm.d(12351):        std.algorithm.nextPermutation(alias less = "a<b", BidirectionalRange)(ref BidirectionalRange range) if (isBidirectionalRange!BidirectionalRange && hasSwappableElements!BidirectionalRange)

那是因为hasSwappableElements!(char[])is false,并且每个nextPermutations' 模板约束它需要true一个类型才能使用nextPermutations

这是false因为所有字符串都被视为范围dchar而不是它们的实际元素类型。这是因为在 UTF- 8 char(每个代码点的单位。本质上,如果 or 的数组被视为 or 的范围,您将面临分解字符的高风险,因此您最终会得到字符片段而不是整个字符。所以,一般在 D 中,如果你想对单个字符进行操作,你应该使用,而不是or 。如果您对 Unicode 不是很熟悉,我建议您阅读这篇文章wchardcharcharwcharcharwchardcharcharwchar乔尔·斯波尔斯基(Joel Spoelsky)关于这个主题。

但是,不管为什么hasSwappableElements!(char[])false,它 false,所以你将需要使用不同的类型。最简单的事情可能就是将您的算法换成使用dchar[]

int[] pandigitals()
{
    dchar[] initial = "123456789"d.dup;
    auto pan = [to!int(initial)];
    while(nextPermutation(initial)) {
       pan ~= to!int(initial);
    }
    return pan;
}
于 2014-06-23T16:33:49.043 回答