【问题标题】:Create array without duplicates c#创建没有重复的数组c#
【发布时间】:2017-03-20 15:41:53
【问题描述】:

这是我现在的代码,我需要帮助,以免重复。我在学校需要这个,所以如果你也能解释一下,那会很有帮助。顺便说一句,它不在乎瑞典语的 cmets

        int temp;

        int[] myArray = new int[20]; // Array med 20 tal
        Random random = new Random(); // Skapar metoden "Random"
        for (int i = 0; i < myArray.Length; i++) // Forloop med 20 positioner
        {

            myArray[i] = random.Next(1, 100); // Ger random värden till dessa 20 positionerna
            for (int j = 0; j < myArray.Length; j++)
            {
                if (myArray[i] > myArray[j]) // Array [i] större än Array [j]
                {
                    //temp = myArray[j];
                    //myArray[j] = myArray[i];  
                    //myArray[i] = temp;

                }
            }
            Console.Write(myArray[i] + " ");
        }

【问题讨论】:

  • 使用HashSet&lt;int&gt; 代替int 的数组,然后执行hashSet.ToArray()
  • 击败我 dcg :) 是的,如果你不关心元素的顺序,HashSet 是你最好的选择
  • 如果这是一项学校任务,仅使用HashSet 很可能是不够的,而是显示其背后的逻辑。
  • 如果您的数组大小为 20,您的随机数范围为 [1;21] 并且您不想要任何重复项,为什么还需要 Random?它看起来更像是您需要将一系列元素 1 到 20 打乱。C# Shuffle
  • 看起来您希望数字 1-20 以随机顺序排列。所以另一种方法是按顺序填充数组,然后对其进行洗牌。例如array = array.OrderBy(x =&gt; random.Next()).ToArray();

标签: c# arrays duplicates


【解决方案1】:

您可以尝试 linq to .Distinct() 并将其转换为数组使用 .ToArray()

var s = { 5, 7, 7, 4, 3};
var q = s.Distinct().ToArray();

【讨论】:

  • 这是为了学校,所以我想他应该在没有 LINQ 的情况下这样做
【解决方案2】:

最简单的,看起来你可能想要

private static Random rng = new Random(); //class level definition

var myArray = Enumerable.Range(1, 20).OrderBy(X => rng.Next()).ToArray();

或者,如果这是用于学校并且您需要证明您的代码的合理性...用数字 1 到 20 填充一个数组,然后使用 Fisher-Yates shuffle 来随机化数组的顺序。

见:https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

【讨论】:

    【解决方案3】:

    由于数组具有随机值范围的大小(即 20),因此您将获得每个数字恰好一次。使用Enumerable.Range 最简单的方法是创建每个号码一次,并且只更改它们出现的顺序。

    更改顺序可以通过OrderBy()来完成,这里使用的是随机的。

    这一切都基于IEnumerable&lt;T&gt;。所以需要放入数组中,只需调用ToArray()即可。

    public int[] RandomlyOrderedValues()
    {
      Random random = new Random();
      return Enumerable.Range(1, 20).OrderBy(x => random.Next()).ToArray();
    }
    

    我不是你的老师,但希望你还是自己玩,阅读文档,最后用你自己的话表达出来。


    改变的问题,现在随机范围大于数组大小。

    IEnumerable&lt;T&gt; 合作始终是最好的选择,在那里您可以获得最强大的工具。

    // let's create inifite number of random values:
    // note that the Random instance needs to be created only once,
    // so it's put into a field.
    
    private Random random = new Random();
    
    public IEnumerable<int> InfiniteRandomValues()
    {
      while (true)
      {
        yield return random.Next(1, 100);
      }
    }
    
    public int[] GetUniqueRandomValues(int numberOfValues)
    {
      return InfiniteRandomValues()
        // only uninque values
        .Distinct()
        // generate the requested number of distinct values
        .Take(numberOfValues)
        // put it into an array.
        .ToArray();
    } 
    

    它是如何工作的?当您创建随机值时,您不知道它将创建多少个,因为您无法知道它将创建多少个重复项。无限数量的值的生成器肯定有足够的值。把它想象成一个工厂。只有当 IEnumerable 被迭代时,才会创建值。

    这称为“延迟执行”。只有当您迭代 IEnumerable 时,源才会请求这些值。

    Distinct 像这样工作。它只返回调用者请求的不同值。

    这是Take。这减少了被占用的项目数量,但仍不会自行迭代。

    ToArray 最终迭代其源并提取尽可能多的值。现在向后阅读:它从 Take 中获取所有值,返回 20。它本身从 Distinct 中获取 20 个值,它迭代它的源直到它得到 20 个不同的值。 Distinct 从InifiteRandomNumbers 工厂获取其值,并且可以根据需要获取任意数量的值。

    当你最终理解了这些东西的工作原理后,你就可以相当直观地使用它了。


    另一个更经典的实现

    private int[] GetRandomValues()
    {
      Random random = new Random();
    
      int[] values = new int[20];
    
      for(int i = 0; i < 20; i++)
      {
        // create random values until you found a distinct oune.
        int nextValue;
        do
        {
          nextValue = random.Next(1, 100);
        } while (ContainsValue(values, i, nextValue))
    
        values[i] = nextValue;
      } 
      return values;
    }
    
    // When adding the values to a List instead of an array, it would be
    // much easier, but need copying the vlaues to the array at the end.
    // When using the array directly, you have to know which values you
    // already generated, because it's initialized with zero.
    // This method checks wether the value is in the array within
    // the items until endIndex.
    private bool ContainsValue(int[] values, int endIndex, int valueToFind)
    {
      // simple linq way:
      // return values.Take(endIndex).Contains(valueToFind);
    
      // classic way:
      for(int i = 0; i < endIndex; i++)
      {
        if (values[i] = valueToFind) return true;
      }
      return false;
    }
    

    【讨论】:

    • 这真的是一个问题的答案,它提到它是为了学校并要求解释?
    • 我想这对于一个学生来说很难理解。
    • 我尽力了。
    猜你喜欢
    • 2022-01-13
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多