C# 素数词典

C# 素数词典,c#,algorithm,data-structures,refactoring,primes,C#,Algorithm,Data Structures,Refactoring,Primes,我试图在C#中创建这个helper函数,它返回前n个素数。我决定将数字以格式存储在字典中。关键是有问题的数字,bool表示int是否为素数。有大量的资源在那里计算/生成素数(包括在内),所以我想通过制作另一个简单的素数生成器来加入大众 我的逻辑如下: public static Dictionary<int,bool> GetAllPrimes(int number) { Dictionary<int, bool> numberArray = ne

我试图在C#中创建这个helper函数,它返回前n个素数。我决定将数字以
格式存储在字典中。关键是有问题的数字,bool表示int是否为素数。有大量的资源在那里计算/生成素数(包括在内),所以我想通过制作另一个简单的素数生成器来加入大众

我的逻辑如下:

public static Dictionary<int,bool> GetAllPrimes(int number)
    {
        Dictionary<int, bool> numberArray = new Dictionary<int, bool>();


        int current = 2;
        while (current <= number)
        {
            //If current has not been marked as prime in previous iterations,mark it as prime
            if (!numberArray.ContainsKey(current))
                numberArray.Add(current, true);

            int i = 2;
            while (current * i <= number)
            {
                if (!numberArray.ContainsKey(current * i))
                    numberArray.Add(current * i, false);
                else if (numberArray[current * i])//current*i cannot be a prime
                    numberArray[current * i] = false;
                i++;

            }
            current++;
        }
        return numberArray;
    }
公共静态字典GetAllPrimes(整数)
{
字典编号raray=新字典();
int电流=2;

然而(当前第一件麻烦的事是,为什么要存储数字本身

你不能只用索引本身来表示数字吗


PS:我不是一个c语言开发者,所以也许用字典是不可能的,但它可以用适当的结构来完成。

第一件麻烦的事是,你为什么要存储数字本身

你不能只用索引本身来表示数字吗


PS:我不是c#开发人员,所以可能不可能使用字典,但可以使用适当的结构来完成。

我非常确定
字典实际上
会影响性能,因为它不能使您以最佳顺序执行试划分。传统上,您会存储已知的pri因为较小的素数比较大的素数具有更多的复合数。此外,您永远不需要尝试与任何大于候选素数平方根的素数除法


许多其他优化都是可能的(正如您自己指出的,这个问题已经被研究到了极点)但是这些都是我能从头顶上看到的。

我很确定
字典实际上
会影响性能,因为它不能使您以最佳顺序执行试验划分。传统上,您会存储已知的素数,以便它们可以从最小到最大进行迭代,因为较小的素数是比较大的素数更多的复合数的因子。此外,您永远不需要尝试与任何大于候选素数平方根的素数除法


许多其他优化都是可能的(正如您自己指出的,这个问题已经被研究到了极点)但是这些都是我能从头顶上看到的。首先,你只需要循环直到数字的平方根。默认情况下,将所有数字设为假,并在每次迭代开始时设置一个简单的标志为真

此外,不要将其存储在字典中。将其设置为bool数组,并将索引设置为您要查找的数字。只有0没有任何意义,但这并不重要。您也不必初始化;bool默认为false。只需声明长度为
number
bool[]

那么,我想这样说:

primes[2] = true;
for(int i = 3; i < sqrtNumber; i += 2) {

}
primes[2]=true;
对于(int i=3;i
所以你会自动跳过所有的偶数

顺便说一句,不要在循环中声明变量(
i
),这样会使循环速度变慢


就是这样。有关更多信息,请参见

,首先,您只需循环到数字的平方根。默认情况下,将所有数字设为false,并在每次迭代开始时设置一个简单的标志

此外,不要将其存储在字典中。将其设置为bool数组,并将索引设置为您要查找的数字。只有0没有任何意义,但这并不重要。您也不必初始化;bool默认为false。只需声明长度为
number
bool[]

那么,我想这样说:

primes[2] = true;
for(int i = 3; i < sqrtNumber; i += 2) {

}
primes[2]=true;
对于(int i=3;i
所以你会自动跳过所有的偶数

顺便说一句,不要在循环中声明变量(
i
),这样会使循环速度变慢

就是这样。有关此函数的更多信息,请从客户端的角度查看1),如果返回类型为bool[](从0到
number
),不是更好吗?在内部,您有三种状态(
knownprome
KnownComposite
Unknown
),可以用枚举表示。在内部存储此枚举的数组,并预先填充
Unknown
,将比字典更快

2) 如果您坚持使用字典,那么将当前数字的倍数标记为复合的筛选部分可以替换为
numberArray.TryGetValue()
模式,而不是多次检查ContainsKey
并随后按键检索值。

1)从该函数的客户端的角度来看,如果返回类型为bool[](可能从0到
number
)不是更好吗?在内部,您有三种状态(
knownprome
knownpomposite
Unknown
),可以用枚举来表示。在内部存储此枚举的数组,并预先填充
Unknown
,将比字典更快


2) 如果您坚持使用字典,那么将当前数字的倍数标记为复合的筛选部分可以替换为
numberArray.TryGetValue()
模式,而不是对
ContainsKey
进行多次检查并随后按键检索值。

字典在这里真的没有意义——只需将所有素数存储到列表中的给定数字。然后按照以下步骤操作:

Is given number in the list? Yes - it's prime. Done. Not in list Is given number larger than the list maximum? No - it's not prime. Done. Bigger than maximum; need to fill list up to maximum. Run a sieve up to given number. Repeat. 名单上有数字吗? 是的,现在是黄金时段,完成了。 不在名单上 给定的数字是否大于列表的最大值? 不,这不是最好的,完成了。 大于最大值;需要将列表填充到最大值。 把筛子筛到给定的数目。 重复 这本词典