【问题标题】:How can I fill array with unique random numbers with for-loop&if-statement?如何使用 for-loop if 语句填充具有唯一随机数的数组?
【发布时间】:2019-06-15 10:55:01
【问题描述】:

我正在尝试用随机但唯一的数字填充一维数组(没有单个数字应该相同)。我猜我在第二个 for 循环中有一个逻辑错误,但无法正确处理。

P.S 我不是在寻找更“复杂”的解决方案——我现在只知道是 while,for,if。 P.P.S 我知道这是一个非常初学者的问题,对这种问题感到抱歉。

        int[] x = new int[10];

        for (int i = 0; i < x.Length; i++)
        {
            x[i] = r.Next(9);

            for (int j = 0; j <i; j++)
            {
                if (x[i] == x[j]) break;

            }
        }
        for (int i = 0; i < x.Length; i++)
        {
            Console.WriteLine(x[i);
        }

【问题讨论】:

  • 只是好奇为什么你必须在这里使用 for 循环和 if 语句?它们在 IMO 解决方案中不是必需的。
  • r.Next(9) 将只返回 0-8 范围内的数字(比参数小一)。您需要将您的 Next 调用更改为 r.Next(10) 以返回 0-9 之间的数字。
  • 老实说,我正在关注其中一本在线课程。所以我正在练习与这些特定的运营商合作。

标签: c# arrays for-loop if-statement random


【解决方案1】:

这是您的代码的解决方案。

    int[] x = new int[10];

    for (int i = 0; i < x.Length;)
    {
        bool stop = false;
        x[i] = r.Next(9);

        for (int j = 0; j <i; j++)
        {
            if (x[i] == x[j]) {
                stop = true;
                break;
            }
        }
        if (!stop)
           i++;
    }
    for (int i = 0; i < x.Length; i++)
    {
        Console.WriteLine(x[i]);
    }

【讨论】:

    【解决方案2】:

    对已发布代码的简单跟踪揭示了一些问题。具体来说,就行了……

    if (x[i] == x[j]) break;
    

    如果随机数“已经”在数组中,那么只需跳出j 循环即可将当前i 值跳过到x 数组中。这意味着每当找到重复项时,x[i] 将是默认值 0(零),然后被跳过。

    外部i循环显然是循环通过xint数组,这很清楚,看起来还可以。然而,第二个内部循环不可能真的是一个for 循环......这就是为什么......基本上你需要找到一个随机的int,然后遍历现有的ints,看看它是否已经存在。鉴于此,理论上您可以“多次”获取相同的随机数,然后才能获得唯一的随机数。因此,在这种情况下……你真的不知道要循环多少次才能找到这个唯一的数字。

    话虽如此,它可能有助于“打破”你的问题。我猜测与x 数组中现有的ints 相比,返回“唯一”int 的“方法”可能会派上用场。创建一个无限的while 循环,在这个循环中,我们将获取一个随机数,然后循环通过“现有的”ints。如果随机数不是重复的,那么我们可以简单地返回这个值。这就是这个方法所做的一切,它可能如下所示。

    private static int GetNextInt(Random r, int[] x, int numberOfRandsFound) {
      int currentRand;
      bool itemAlreadyExist = false;
      while (true) {
        currentRand = r.Next(RandomNumberSize);
        itemAlreadyExist = false;
        for (int i = 0; i < numberOfRandsFound; i++) {
          if (x[i] == currentRand) {
            itemAlreadyExist = true;
            break;
          }
        }
        if (!itemAlreadyExist) {
          return currentRand;
        }
      }
    }
    

    注意:现在是描述这段代码中可能出现的无限循环的好时机……

    目前,随机数和数组的大小是相同的,但是,如果数组大小“大于”随机数扩展,那么上面的代码将永远不会退出。例如,如果当前 x 数组的大小设置为 11 并且随机数保留为 10,那么您将永远无法设置 x[10] 项,因为所有可能的随机数都已使用。我希望这是有道理的。

    一旦我们有了上面的方法……剩下的应该是相当简单的。

    static int DataSize;
    static int RandomNumberSize;
    
    static void Main(string[] args) {
      Random random = new Random();
      DataSize = 10;
      RandomNumberSize = 10;
      int numberOfRandsFound = 0;
      int[] ArrayOfInts = new int[DataSize];
      int currentRand;
      for (int i = 0; i < ArrayOfInts.Length; i++) {
        currentRand = GetNextInt(random, ArrayOfInts, numberOfRandsFound);
        ArrayOfInts[i] = currentRand;
        numberOfRandsFound++;
      }
      for (int i = 0; i < ArrayOfInts.Length; i++) {
        Console.WriteLine(ArrayOfInts[i]);
      }
      Console.ReadKey();
    }          
    

    最后正如其他人所提到的,使用List&lt;int&gt; 会更容易...

    static int DataSize;
    static int RandomNumberSize;
    
    static void Main(string[] args) {
      Random random = new Random();
      DataSize = 10;
      RandomNumberSize = 10;
      List<int> listOfInts = new List<int>();
      bool stillWorking = true;
      int currentRand;
      while (stillWorking) {
        currentRand = random.Next(RandomNumberSize);
        if (!listOfInts.Contains(currentRand)) {
          listOfInts.Add(currentRand);
          if (listOfInts.Count == DataSize)
            stillWorking = false;
        }
      }
      for (int i = 0; i < listOfInts.Count; i++) {
        Console.WriteLine(i + " - " + listOfInts[i]);
      }
      Console.ReadKey();
    }
    

    希望这会有所帮助;-)

    【讨论】:

    • 希望我能有你这样的导师!谢谢,对我帮助很大。
    【解决方案3】:

    典型的解决方案是依次生成整个潜在集(在本例中是一个值从 0 到 9 的数组)。然后打乱序列。

    private static Random rng = new Random();  
    
    public static void Shuffle(int[] items)  
    {  
        int n = list.Length;  
        while (n > 1) {  
            n--;  
            int k = rng.Next(n + 1);  
            int temp = items[k];  
            items[k] = items[n];  
            items[n] = temp;  
        }  
    }
    
    static void Main(string[] args)
    {
        int[] x = new int[10];
        for(int i = 0; i<x.Length; i++)
        {
            x[i] = i;
        }
    
        Shuffle(x);
    
        for(int i = 0; i < x.Length; i++)
        {
            Console.WritLine(x[i]);
        }
    } 
    
    //alternate version of Main()
    static void Main(string[] args)
    {
        var x = Enumerable.Range(0,10).ToArray();
        Shuffle(x);
        Console.WriteLine(String.Join("\n", x));  
    } 
    

    【讨论】:

      【解决方案4】:

      你可以这样做:

      private void AddUniqueNumber()
      {  
         Random r = new Random();
         List<int> uniqueList = new List<int>();
         int num = 0, count = 10;
         for (int i = 0; i < count; i++)
         {
             num = r.Next(count);
      
             if (!uniqueList.Contains(num))
                uniqueList.Add(num);
         }
      }
      
      Or:
      
      int[] x = new int[10];
      Random r1 = new Random();
      int num = 0;
      for (int i = 0; i < x.Length; i++)
      {
          num = r1.Next(10);
          x[num] = num;
      }
      

      【讨论】:

      • OP 不想要更复杂的解决方案,这是为初学者准备的 :-)
      • 还是不行。如果 rng 滚动重复数字,则答案中的第一个版本根本不会填充整个数组,并且第二个选项不会检查以确保项目是唯一的,并且还可能留下未分配的元素。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-08
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      相关资源
      最近更新 更多