簡體   English   中英

猜數字的程序變得異常緩慢

[英]Program to guess number gets incredibly slow

因此,我決定找點樂子,制作一個可以提供數字的程序,您必須猜測一下它是否告訴您您過高/過低。 但是,我決定,如果計算機可以自己提供隨機數,那會更好玩。

我在這里使用一種簡單的方法,該方法基本上可以讓程序檢查一個值是否在array ,如果是,則給出另一個隨機數。 當數字太大時,從數字的大小開始,然后減小到該數字(這樣,如果數字太大,則永遠不會再猜到該數字更高或更高)。

因此,這對於少量數字非常有用。 我認為當做一個像1000之類的數字時,它在15次嘗試中就猜到了。 但是,當我做10,000,000時(我知道這有點極端,但是我想了解C#的強大功能,因為我對這種語言還很陌生)。

該程序獲得了大約10個猜測,並且開始顯着降低速度。 我已經設置了一個250ms的睡眠計時器,使它看起來更像是在猜測(因為它在1,000或10,000之類的情況下是即時的),但是取出時它仍然變慢了。 我認為這可能是因為,如果它猜測一個類似300萬的數字,則必須將700萬個值添加到數組中(我使用的是List以便它具有“無限”值)。

那么我現在該怎么辦? 我希望它能夠猜測大量數字,但目前看來似乎還不可能。 我該怎么辦?

這是我的代碼:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Program {
    class Program {
        static void Main(string[] args) {
            Random random = new Random();
            int selectedNumber = random.Next(1, 101);
            int maxNumber;
            int guessNumber = 0;
            int inputNumber = 0;
            // Intro
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("Welcome to the High Low - Computer version program!");
            System.Threading.Thread.Sleep(4000);
            Console.WriteLine("\n--------------------------------------------------------");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            // This way the computer guesses rather than you
            char who = 'C';
            Console.Write("\nHow high do you want the computer's number to be max > ");
            maxNumber = Convert.ToInt32(Console.ReadLine());
            List<int> guessedNumbers = new List<int>();
            selectedNumber = random.Next(1, maxNumber);
            do {
                // System.Threading.Thread.Sleep(250);
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                if (who == 'M') {
                    Console.Write("\nPlease enter your guess > ");
                    guessNumber = Convert.ToInt32(Console.ReadLine());
                }
                else {
                    while (true) {
                        guessNumber = random.Next(1, maxNumber);
                        if (!(guessedNumbers.Contains(guessNumber))) {
                            guessedNumbers.Add(guessNumber);
                            inputNumber++;
                            break;
                        }
                    }
                    Console.WriteLine("Please enter your guess > {0}", guessNumber);
                }
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                if (guessNumber < selectedNumber) {
                    Console.WriteLine("\nYou're guessing too low!\n");
                    for (int i = 0; i < guessNumber; i++) {
                        guessedNumbers.Add(i);
                        inputNumber++;
                    }
                }
                else if (guessNumber > selectedNumber) {
                    Console.WriteLine("\nYou're guessing too high!\n");
                    for (int i = maxNumber; i > guessNumber; i--) {
                        guessedNumbers.Add(i);
                        inputNumber++;
                    }
                }
            } while (guessNumber != selectedNumber);
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("\nCongratulations! You correctly guessed that {0} is the computer's number!", selectedNumber);
            Console.ReadKey();
        }
    }
}

編輯:我想我會嘗試一種方法來做到這一點,以便它只添加不在其中的更高或更低的數字,以防止出現重復的數字。

for (int i = 0; i < guessNumber; i++) 
{
    guessedNumbers.Add(i);
    inputNumber++;
}

每次輸入這些類型的循環時,都會將“ guessnumber”項添加到列表中,可能是數百萬。

考慮重新閱讀代碼並理解它的作用。

另外,您應該考慮封裝代碼,以免使main()龐然大物

另一種方法是使用二進制搜索方法來猜測數字,並避免由於編寫和搜索猜測值而導致的額外開銷。

這應該在O(log n).

int minGuess = 0;
int maxGuess = 1000000;

Random random = new Random();
int selectedNumber = random.Next(minGuess, maxGuess);

Console.WriteLine($"Selected number: {selectedNumber}");

int guess;

int count = 0;

do
{
    count++;

    guess = (minGuess + maxGuess) / 2;

    Console.WriteLine($"Guess: {guess}");

    if (selectedNumber < guess)
        maxGuess = guess - 1;
    else
        minGuess = guess + 1;

} while (guess != selectedNumber);

Console.WriteLine($"Guessed it in {count} tries");
Console.ReadLine();

您嘗試使用計算機的電源查找數字的方式並不是很有效,為什么不根據以前猜測的數字是高於還是低於正確的數字來更改可能的猜測數字的范圍,例如所以:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Highest number:");
            int maxNumber = Convert.ToInt32(Console.ReadLine());
            Random rand = new Random();
            int correctNumber = rand.Next(0, maxNumber);

            Console.WriteLine("Trying to guess number now..");
            int guessedNumber = 0;

            int lowBound = 0;
            int highBound = maxNumber;
            int guesses = 0;
            while(guessedNumber != correctNumber)
            {
                guessedNumber = rand.Next(lowBound, highBound);
                if(guessedNumber > correctNumber)
                {
                    highBound /= 2;
                    lowBound /= 2;
                }
                else if(guessedNumber < correctNumber)
                {
                    lowBound *= 2;
                    highBound *= 2;
                }
                ++guesses;
            }
            Console.WriteLine($"Took me {guesses} guesses.");
            Console.ReadKey();
        }
    }

對於我的機器上的10,000,000個條目,此過程不到一秒鍾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM