大家下午好,我有一个关于学校要解决的问题,因为它与Collatz问题相关,我需要开发一个应用程序,它将找出产生最大序列的1到100万之间的起始数字
我在不使用LINQ的情况下制作了以下代码,并且想知道在这种情况下如何使用linq。
var sequence_size = 0;
var best_number = 0;
var sequence = 0;
for (var i = 0; i <= 1000000; i ++)
{
var size_ = 1;
sequence = i;
while (sequence! = 1)
{
sequence = sequence% 2 == 0? sequence / 2: sequence * 3 + 1;
size ++;
}
if (size> size)
{
size_sequence = size;
best_number = i;
}
}
答案 0 :(得分:0)
这是我建议的:
public class MaxSequenceFinder
{
public int FindBestCollatzSequence(int start, int count)
{
return Enumerable.Range(start, count)
.Select(n => new { Number = n, SequenceLength = CalcCollatzSequence((long)n) })
.Aggregate((i, j) => i.SequenceLength > j.SequenceLength ? i : j)
.Number;
}
private int CalcCollatzSequence(long n)
{
int sequenceLength = 0;
do
{
n = CalcNextTerm(n);
sequenceLength++;
}
while (n != 1);
return sequenceLength;
}
private long CalcNextTerm(long previousTerm)
{
return previousTerm % 2 == 0 ? previousTerm / 2 : previousTerm * 3 + 1;
}
}
可以这样使用:
var finder = new MaxSequenceFinder();
int result = finder.FindBestCollatzSequence(1, 100);
Console.WriteLine(result);
运行计数为1 000 000需要一些时间。但在这种情况下(<100),最长的序列是:
97
答案 1 :(得分:0)
创建一个扩展函数,使用每个元素上的函数找到序列的最大值:
public static class Ext {
public static T MaxBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> key, Comparer<TKey> keyComparer = null) {
keyComparer = keyComparer ?? Comparer<TKey>.Default;
return src.Aggregate((a,b) => keyComparer.Compare(key(a), key(b)) > 0 ? a : b);
}
}
创建一个函数以返回数字的Collatz长度:
public long Collatz(long seq) {
long len = 0;
while (seq != 1) {
if (seq % 2 == 0) {
seq /= 2;
++len;
}
else {
seq = (3 * seq + 1) / 2;
len += 2;
}
}
return len;
}
然后你可以使用这些和LINQ来计算范围的答案:
var maxn = Enumerable.Range(2, 1000000-2).Select(n => new { n, Collatz = Collatz(n) }).MaxBy(nc => nc.Collatz).n;