我正在尝试解决代码大战中的问题,所提供的单元测试完全没有意义......
问题如下,听起来非常简单,可以在5分钟内完成工作
Consider a sequence u where u is defined as follows:
The number u(0) = 1 is the first one in u.
For each x in u, then y = 2 * x + 1 and z = 3 * x + 1 must be in u too.
There are no other numbers in u.
Ex: u = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]
1 gives 3 and 4, then 3 gives 7 and 10, 4 gives 9 and 13, then 7 gives 15 and 22 and so on...
Task:
Given parameter n the function dbl_linear (or dblLinear...) returns the element u(n) of the ordered (with <) sequence u.
Example:
dbl_linear(10) should return 22
起初我使用带有linq查询的一个sortedset,因为我并不真正关心效率,我很快就知道这个操作必须计算到n在12秒内可以等于~100000的范围。
所以这种憎恶诞生了,然后一次又一次地被屠杀,因为for循环会因某种原因产生问题。然后它被“升级”为一个while循环,它给出了更多的单元测试(4 - > 8)。
public class DoubleLinear {
public static int DblLinear(int n) {
ListSet<int> table = new ListSet<int> {1};
for (int i = 0; i < n; i++) {
table.Put(Y(table[i]));
table.Put(Z(table[i]));
}
table.Sort();
return table[n];
}
private static int Y(int y) {
return 2 * y + 1;
}
private static int Z(int z) {
return 3 * z + 1;
}
}
public class ListSet<T> : List<T> {
public void Put(T item) {
if (!this.Contains(item))
this.Add(item);
}
}
使用此代码仍然无法计算超过n = 75000,但最多可以进行8次测试。
我已经检查过其他人是否通过了这个,他们有。但是,我无法检查他们写的东西,以便从中学习。
任何人都可以提供有关此处可能出现的错误的见解吗?我确定答案显而易见,而且我很愚蠢。
也是这样使用自定义列表一个坏主意?有更好的方法吗?
答案 0 :(得分:1)
ListSet对于排序很慢,并且在构建集合时不断获得内存重新分配。我首先要先分配完整大小的表格,但老实说,我也会告诉你使用你需要的大小数量的准系统最适合性能。
如果您知道您需要n = 75,000+,请分配该大小的ListSet(或ARRAY!)。如果单元测试开始带你进入平流层,我们可以讨论一种二进制分割技术,但这有点涉及并且逻辑上难以构建。
我没有看到任何逻辑错误的代码。它产生的数字在我站立的地方是正确的。
编辑:因为你知道3n + 1&gt; 2n + 1,你只需要保持6个值:
Target index in u
Current index in u
Current x for y
Current x for z
Current val for y
Current val for z
public static int DblLinear(int target) {
uint index = 1;
uint ind_y = 1;
uint ind_z = 1;
uint val_y = 3;
uint val_z = 4;
if(target < 1)
return 1;
while(index < target) {
if(val_y < val_z) {
ind_y++;
val_y = 2*ind_y + 1;
} else {
ind_z++;
val_z = 3*ind_z + 1;
}
index++;
}
return (val_y < val_z) ? val_y : val_z;
}
如果要将分支扩展为2个条件,或者在超出目标索引时实现后退循环,则可以修改val_y if if为while循环(更有效的关键路径)。
没有内存分配肯定会加快你的计算速度,即使是人们想要(错误地)在这种容易预测的情况下对分支预测感到不适。
另外,您是否在Visual Studio项目中启用了优化?如果您提交的是二进制文件而不是代码文件,那么这也可以节省相当多的时间。