我有n个元素.为了举个例子,让我们说,7个元素,1234567.我知道有7个!=这些7个元素可能有5040个排列.
我想要一个包含两个函数的快速算法:
f(number)将0到5039之间的数字映射到唯一的排列,并且
f'(置换)将置换映射回其生成的数字.
我不关心数字和排列之间的对应关系,只要每个排列都有自己唯一的数字.
所以,举个例子,我可能会在哪里有功能
f(0) = '1234567'
f'('1234567') = 0
Run Code Online (Sandbox Code Playgroud)
想到的最快的算法是枚举所有排列并在两个方向上创建查找表,这样,一旦创建表,f(0)将是O(1)并且f('1234567')将是查找字符串.然而,这是内存饥饿,特别是当n变大时.
任何人都可以提出另一种算法,它可以快速工作,没有内存缺点吗?
我有以下代码:
public struct Num<T>
{
private readonly T _Value;
public Num(T value)
{
_Value = value;
}
static public explicit operator Num<T>(T value)
{
return new Num<T>(value);
}
}
...
double d = 2.5;
Num<byte> b = (Num<byte>)d;
Run Code Online (Sandbox Code Playgroud)
这段代码编译,令我惊讶.显式转换应该只接受a byte而不是a double.但双重被接受了.当我在转换器中放置断点时,我发现它value已经是byte有价值的2.通过从double到byte的转换应该是显式的.
如果我用ILSpy反编译我的EXE,我会看到下一个代码:
double d = 2.5;
Program.Num<byte> b = (byte)d;
Run Code Online (Sandbox Code Playgroud)
我的问题是:来自哪里的额外演员byte?为什么那里有额外的演员?我的演员去Num<byte>哪儿了?
编辑
结构Num<T>是整个结构,所以没有更多隐藏的额外方法或运算符.
按要求编辑 IL:
IL_0000: nop
IL_0001: ldc.r8 2.5 // Load the double 2.5. …Run Code Online (Sandbox Code Playgroud)