我试图将我的表演技巧(不存在)提升到标准杆,但是在将代码写入代码时遇到了问题。这是我尝试的公式 - 引用unquote - " convert"代码。
考虑一个序列u,其中u的定义如下:
数字
u(0) = 1
是u
中的第一个。 对于x
中的每个u
,y = 2 * x + 1
和z = 3 * x + 1
也必须位于u
。u
中没有其他数字。 例如:u = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]
1
提供3
和4
,然后3
提供7
和10
,4
提供9
}和13
,然后7
提供15
和22
等等......
这就是我到目前为止所做的:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine(DblLinear(10));
//Expected result: 22
Console.WriteLine(DblLinear(20));
//Expected result: 57
Console.WriteLine(DblLinear(30));
//Expected result: 91
Console.WriteLine(DblLinear(50));
//Expected result: 175
}
public static int DblLinear (int n)
{
List<int> linArr = new List<int>();
linArr.Add(1);
int i = 0;
while(linArr.Count < n)
{
linArr.Add((2 * linArr[i]) + 1);
linArr.Add((3 * linArr[i]) + 1);
linArr.Sort();
i++;
}
return linArr[n - 1];
}
}
计算是正确的,直到它达到27.然后它只是狂奔,我不知道它做错了什么。
答案 0 :(得分:5)
你从序列中取出一个项目并产生两个。所以你真的需要一些数据结构来存储它们,因为它们的数量会增加。堆将是最好的。如果您想直接使用.net中的内容,可以使用SortedSet
。
public static IEnumerable<int> DblLinear2()
{
SortedSet<int> seq = new SortedSet<int> { 1 };
while (true)
{
int min = seq.First();
seq.Remove(min);
yield return min;
seq.Add(min * 2 + 1);
seq.Add(min * 3 + 1);
}
}
结果:
1,3,4,7,9,10,13,15,19,21,22,27,28,31,39,40,43,45,46, 55,57,58,63,64,67,79,81,82,85,87 ......
答案 1 :(得分:2)
出现问题的是您使用单个索引来构建您的值。
当你到达i == 27
时,根据你的例子,第一个系列产生55
,第二个系列产生82
。但第一个应该在第二个产生57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81
之前生成82
,以便正确计算序列。
您需要运行两个单独的索引,并且只有当它们各自系列产生的值最低(或等于另一个)时,才会递增每个索引。
这是我将如何做到的:
public static IEnumerable<int> DblLinear()
{
Func<int, int> fxy = x => 2 * x + 1;
Func<int, int> fxz = x => 3 * x + 1;
var intermediate = new System.Collections.Generic.SortedSet<int>();
Action<int> safeAdd = x =>
{
if (!intermediate.Contains(x))
{
intermediate.Add(x);
}
};
safeAdd(1);
while (true)
{
var x = intermediate.First();
safeAdd(fxy(x));
safeAdd(fxz(x));
intermediate.Remove(x);
yield return x;
}
}
现在可以使用它来生成整个序列,因此最好使用LINQ .Take(...)
运算符。
您可以像这样使用它:
Console.WriteLine(String.Join(", ", DblLinear().Take(20)));
......这让我:
1,3,4,7,9,10,13,15,19,21,22,27,28,31,39,40,43,45,46,55
您的测试代码经过修改以处理列表,可以正常工作:
Console.WriteLine(DblLinear().Skip(10).First());
//Expected result: 22
Console.WriteLine(DblLinear().Skip(20).First());
//Expected result: 57
Console.WriteLine(DblLinear().Skip(30).First());
//Expected result: 91
Console.WriteLine(DblLinear().Skip(50).First());
//Expected result: 175