我正在尝试根据用户输入生成素数。这是我到目前为止所得到的,但我似乎无法弄明白:
Console.Write("Please enter the number of prime numbers you would like to see:");
int numberOfPrimes = Convert.ToInt32(Console.ReadLine());
for (int x = 0; x < numberOfPrimes; x++)
{
for (int a = 2; a <= x ; ++a)
{
bool prime = true;
for (int b = 2; b < a; ++b)
{
if (a % b == 0)
{
prime = false;
}//end if
}//end double nested for
if (prime == true)
{
Console.WriteLine(a);
}//end if
}//end nested for
}//end for
答案 0 :(得分:3)
如果你看一下你的循环结构,你应该能够很容易地看出你的结果错误的原因。手工完成它们(不会花很长时间)。
您获得当前结果的原因是外循环(x < numberOfPrimes
)的每次迭代都不会产生结果 - 由于内部循环的结构方式,它将跳过相当多的迭代。 / p>
你真正需要做的是重构内循环。你最内层的循环工作正常,应该检测任何素数。但是,您的第二个循环应该只测试尚未测试的数字。此外,一旦找到素数,它应该停止循环。
答案 1 :(得分:1)
你应该更好地构建你的代码,它现在的方式非常麻烦。有一个方法IsPrime(int x)
如果x
为素数则返回true,否则返回false。
然后,要生成numberOfPrimes
素数,您可以执行以下操作:
for ( int primeCount = 0, currentPrime = 2; primeCount < numberOfPrimes; ++currentPrime )
if ( IsPrime(currentPrime) )
{
// do whatever you want with currentPrime, like print it
++primeCount;
}
或者使用Sieve of Eratosthenes,这是一种更快的方法。
要确定某个号码x
是否为素数,请尝试2
和Sqrt(x)
之间的所有因素。为什么只有Sqrt(x)
?因为如果是a*b = x
,那么x / b = a
和x / a = b
,那么你会检查所有内容两次,如果你去x / 2
甚至{{ 1}}。
如果你想使用x
函数,那就是这样:
IsPrime(x)
但我建议你使用Eratosthenes的筛子,因为它要快得多。你也可以优化一些东西,这样你就不会检查偶数,因为偶数是绝对的,除了2(在筛子和天真的方法中)。将x = 2视为边缘情况,然后开始检查每隔一个数字(3,5,7,9,11等)
答案 2 :(得分:0)
一旦你完成了循环整理,你只需要检查b&lt; sqrt(a),任何更高,你会先找到另一个因素。
答案 3 :(得分:0)
您正在寻找的是“Eratosthenes的筛子”。因为我不做人的作业,这是我要给你的唯一线索。该算法很容易在互联网上找到。
答案 4 :(得分:0)
下一个素数(x) - 是不能被所有素数s除的数,即s <= sqrt(x)。 所以你可以使用像
这样的功能public bool CheckAndAddPrime(int number,List<int> primes)
{
var sqrt = Math.Sqrt(number);
foreach(var prime in primes)
{
if(prime>sqrt) break;
if(number % prime == 0) return false;
}
primes.Add(number);
return true;
}
而且你可以获得像
这样的素数var primes = new List<int>();
Enumerable.Range(2,int.MaxValue).Where(x => x.CheckAndAddPrime(x,primes)).Take(YouCountOfPrimes);
答案 5 :(得分:0)
var primes = Enumerable.Range(1, numberOfPrimes )
.Where(x => x != 1 &&
!Enumerable.Range2, (int)Math.Sqrt(x)).Any(y => x != y && x % y == 0));
static void Main(string[] args)
{
foreach (int no in get_first_k_primes(10))
{
Console.Write(" "+no.ToString() );
}
}
public static List<int> get_first_k_primes(int k)
{
var primes = new List<int>();
primes.Add(2);
int i = 3;
while(primes.Count < k)
{
if(is_prime(i))
primes.Add(i);
i += 2;
}
return primes;
}
public static bool is_prime(int n)
{
if (n % 2 == 0 && n != 2) return false;
int m = (int)Math.Ceiling(Math.Sqrt(n));
for (int i = 3; i < m; i += 2)
{
if (n % i == 0) return false;
}
return true;
}
答案 6 :(得分:0)
<强> 1。重命名变量。
首先,如果这是作业,你会得到不好的分数(如果你的老师值得他的盐),因为你有无意义的变量名称(是的,即使numberOfPrimes
是错误的,应该命名为requiredNumberOfPrimes
。当我看到这个变量时,我会问自己'这是他想要多少,或者他找到了多少?')。
其次,它会帮助您了解出错的地方。变量应根据它们代表的内容进行逻辑命名。如果你无法解释你的变量代表什么(例如a&amp; b)那么你可能无法解释你在用它们做什么。
<强> 2。看看你的循环。
for (int x = 0; x < numberOfPrimes; x++)
for循环的结构是(initialise; 'should I continue?'; 'each loop do this')
。因此在你的循环中
numberOfPrimes
*。x
添加1。你确定这是你想做的吗? x
似乎代表您找到的素数。那么为什么不在找到素数时增加它,而不是在开始循环时增加它?
for (int a = 2; a <= x ; ++a)
for (int b = 2; b < a; ++b)
您正在查看介于2和x
之间的每个整数。对于每个整数a
,您正在查看a
和2之间的每个整数。你打算用这些整数做什么?
每次循环浏览顶级循环(x
循环)时,您将从头开始a
循环,每次循环遍历a
循环,您将从头开始b
循环。
因此,如果x
为10,则运行一次(a = 2),然后再次运行a(a = 2,a = 3),然后再次运行a(a = 2) ,a = 3,a = 4),然后......
第3。收集结果而不是将其写入控制台。
var primes = new List<int>();
这很容易。当你找到素数时,primes.Add(a);
。然后你知道你找到了多少素数(primes.Count
),你可以使用素数列表来有效地确定下一个素数,如果需要你可以稍后使用该列表。