كيف يمكنك إنشاء كمية محددة من المستخدمين من الأرقام الرئيسية؟

StackOverflow https://stackoverflow.com/questions/2415033

  •  19-09-2019
  •  | 
  •  

سؤال

أحاول توليد الأرقام الرئيسية بناء على إدخال المستخدم. هذا هو ما لدي حتى الآن ولكني لا أستطيع أن يبدو أنه معرفة ذلك:

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
هل كانت مفيدة؟

المحلول

يجب أن تكون قادرا على معرفة سبب ظهور نتائجك بسهولة تماما إذا نظرت إلى هياكل الحلقة الخاصة بك. خطوة من خلالها باليد (لن يستغرق وقتا طويلا).

السبب في الحصول على نتائجك الحالية هو أنه ليس كل تكرار للحلقة الخارجية (x < numberOfPrimes) تنتج نتيجة - سوف تخطي عدد قليل من التكرارات بسبب الطريقة التي يتم بها منظم الحلقة الداخلية.

ما تحتاجه حقا للقيام به هو إعادة هيكلة الحلقات الداخلية. يعمل حلقة Innermost الخاصة بك بشكل جيد، ويجب أن تكتشف أي أرقام أولى. ومع ذلك، يجب على حلقةك الثانية فقط اختبار الأرقام التي لم يتم اختبارها بعد. أيضا، يجب أن تتوقف عن الحلقات بمجرد العثور على رقم رئيسي.

نصائح أخرى

يجب عليك بناء الرمز الخاص بك بشكل أفضل، فمن الفوضى حقا الطريقة التي تقوم بها الآن. لديك طريقة IsPrime(int x) الذي يعود صحيح إذا x هو رئيس الوزراء والخطال خلاف ذلك.

ثم، لتوليد numberOfPrimes الأعداد الأولية، يمكنك القيام بشيء مثل هذا:

for ( int primeCount = 0, currentPrime = 2; primeCount < numberOfPrimes; ++currentPrime )
  if ( IsPrime(currentPrime) )
  {
    // do whatever you want with currentPrime, like print it
    ++primeCount;
  }

أو استخدام غربال eratosthenes., ، وهي طريقة أسرع بكثير.

لمعرفة ما إذا كان هناك عدد x هو رئيس أو لا، حاول كل عواملها بين 2 و Sqrt(x). وبعد لماذا فقط Sqrt(x)ب لأنه إذا a*b = x, ، ومن بعد x / b = a و x / a = b, ، لذلك سوف تحقق كل شيء مرتين، وأيضا تحقق من الأشياء التي يجب ألا يجب أن تصل إلى x / 2 او حتى x.

لذلك شيء من هذا القبيل إذا كنت تريد استخدام IsPrime(x) وظيفة:

// i <= Sqrt(x) <=> i * i <= x
for ( int i = 2; i * i <= x; ++i )
  if ( x % i == 0 )
    return false;

return true;

لكنني أقترح عليك استخدام غربال eratosthenes، لأنها أسرع بكثير. يمكنك أيضا تحسين الأشياء حتى لا تحقق من الأرقام، نظرا لأن عدد حتى ليس رئيسا أبدا، باستثناء 2 (في الغربال والطريقة الساذجة). علاج X = 2 كحالة حافة ثم ابدأ في التحقق من كل رقم آخر (3، 5، 7، 9، 11 إلخ)

ما تبحث عنه يسمى "غربال eratosthenes". بما أنني لست في القيام بواجب الناس، فهذا هو الدليل الوحيد الذي سأعطيك. يتم العثور على الخوارزمية بسهولة على الإنترنت.

الرقم الرئيسي التالي (x) - هو الرقم الذي لا يمكن أن تقطع به جميع الأعداد الأولية 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);
var primes = Enumerable.Range(1, numberOfPrimes )
    .Where(x => x != 1 &&
      !Enumerable.Range2, (int)Math.Sqrt(x)).Any(y => x != y && x % y == 0));

نسخ من Codethinked.com.

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;
}

1. إعادة تسمية المتغيرات الخاصة بك.

أولا، إذا كان هذا هو الواجبات المنزلية، فستحصل على علامات سيئة (إذا كان معلمك يستحق ملحه) لأنك أسماء متغيرة بلا معنى (نعم، حتى numberOfPrimes غير صحيح وينبغي اسمه requiredNumberOfPrimes. وبعد عندما أرى هذا المتغير، أطلب نفسي "هل هذا ما يريده، أو كم وجد؟").

ثانيا، سوف يساعدك على فهم المكان الذي تسير فيه. يجب تسمية المتغيرات بشكل منطقي وفقا لما يمثلونه. إذا لم تتمكن من شرح ما تمثل المتغيرات الخاصة بك (مثل A & B)، فربما لا يمكنك شرح ما تفعله معهم.

2. انظر إلى حلقاتك.

for (int x = 0; x < numberOfPrimes; x++)

هيكل حلقة (initialise; 'should I continue?'; 'each loop do this'). وبعد لذلك في حلقة الخاص بك

  • أنت مستمر حتى تساوي x أو عظيم من numberOfPrimes*.
  • في كل مرة تذهب فيها من خلال الحلقة التي تضيفها 1 إلى x.

هل أنت متأكد من أن هذا ما تريد أن تفعله؟ 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 = 2، A = 3)، ثم تشغيلك مرة أخرى (a = 2، a = 3، a = 4)، ومن بعد...

3. جمع نتائجك بدلا من كتابةها إلى وحدة التحكم.

var primes = new List<int>();

إنه سهل للغاية. عندما تجد رئيسا، primes.Add(a);. وبعد ثم تعرف عدد الأعداد الأولية التي وجدتها (primes.Count)، يمكنك استخدام قائمة الأعداد الأولية لتحديد PRIME التالي، ويمكنك استخدام القائمة في وقت لاحق إذا لزم الأمر.

بمجرد أن تحصل على حلقات iThe تم فرزها، يجب عليك فقط التحقق من B <SQRT (A)، أي أعلى وكنت قد وجدت العامل الآخر أولا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top