Check for missing number in sequence

前端 未结 14 1538
太阳男子
太阳男子 2020-12-04 17:58

I have an List which contains 1,2,4,7,9 for example.

I have a range from 0 to 10.

Is there a way to determine what numbers are missin

相关标签:
14条回答
  • 2020-12-04 18:14

    An alternative method which works in general for any two IEnunumerable<T> where T :IComparable. If the IEnumerables are both sorted, this works in O(1) memory (i.e. there is no creating another ICollection and subtracting, etc.) and in O(n) time.

    The use of IEnumerable<IComparable> and GetEnumerator makes this a little less readable, but far more general.

    Implementation

    /// <summary>
    /// <para>For two sorted IEnumerable&lt;T&gt; (superset and subset),</para>
    /// <para>returns the values in superset which are not in subset.</para>
    /// </summary>
    public static IEnumerable<T> CompareSortedEnumerables<T>(IEnumerable<T> superset, IEnumerable<T> subset)
        where T : IComparable
    {
        IEnumerator<T> supersetEnumerator = superset.GetEnumerator();
        IEnumerator<T> subsetEnumerator = subset.GetEnumerator();
        bool itemsRemainingInSubset = subsetEnumerator.MoveNext();
    
        // handle the case when the first item in subset is less than the first item in superset
        T firstInSuperset = superset.First();
        while ( itemsRemainingInSubset && supersetEnumerator.Current.CompareTo(subsetEnumerator.Current) >= 0 )
            itemsRemainingInSubset = subsetEnumerator.MoveNext();
    
        while ( supersetEnumerator.MoveNext() )
        {
            int comparison = supersetEnumerator.Current.CompareTo(subsetEnumerator.Current);
            if ( !itemsRemainingInSubset || comparison < 0 )
            {
                yield return supersetEnumerator.Current;
            }
            else if ( comparison >= 0 )
            {
                while ( itemsRemainingInSubset && supersetEnumerator.Current.CompareTo(subsetEnumerator.Current) >= 0 )
                    itemsRemainingInSubset = subsetEnumerator.MoveNext();
            }
        }
    }
    

    Usage

    var values = Enumerable.Range(0, 11);
    var list = new List<int> { 1, 2, 4, 7, 9 };
    var notIncluded = CompareSortedEnumerables(values, list);
    
    0 讨论(0)
  • 2020-12-04 18:16

    Using Unity i have tested two solutions on set of million integers. Looks like using Dictionary and two "for" loops gives better result than Enumerable.Except

    FindMissing1 Total time: 0.1420 (Enumerable.Except)
    FindMissing2 Total time: 0.0621 (Dictionary and two for loops)

    public static class ArrayExtension
    {
        public static T[] FindMissing1<T>(T[] range, T[] values)
        {
            List<T> result = Enumerable.Except<T>(range, values).ToList<T>();
            return result.ToArray<T>();
        }
    
        public static T[] FindMissing2<T>(T[] range, T[] values)
        {
            List<T> result = new List<T>();
            Dictionary<T, T> hash = new Dictionary<T, T>(values.Length);
            for (int i = 0; i < values.Length; i++)
                hash.Add(values[i], values[i]);
    
            for (int i = 0; i < range.Length; i++)
            {
                if (!hash.ContainsKey(range[i]))
                    result.Add(range[i]);
            }
    
            return result.ToArray<T>();
        }
    }
    
    public class ArrayManipulationTest : MonoBehaviour
    {
        void Start()
        {
            int rangeLength = 1000000;
            int[] range = Enumerable.Range(0, rangeLength).ToArray();
            int[] values = new int[rangeLength / 5];
            int[] missing;
            float start;
            float duration;
    
            for (int i = 0; i < rangeLength / 5; i ++)
                values[i] = i * 5;
    
            start = Time.realtimeSinceStartup;
            missing = ArrayExtension.FindMissing1<int>(range, values);
            duration = Time.realtimeSinceStartup - start;
            Debug.Log($"FindMissing1 Total time: {duration:0.0000}");
    
            start = Time.realtimeSinceStartup;
            missing = ArrayExtension.FindMissing2<int>(range, values);
            duration = Time.realtimeSinceStartup - start;
            Debug.Log($"FindMissing2 Total time: {duration:0.0000}");
        }
    }
    
    0 讨论(0)
  • 2020-12-04 18:17

    If the range is predictable I suggest the following solution:

    public static void Main()
    {
        //set up the expected range
        var expectedRange = Enumerable.Range(0, 10);
    
        //set up the current list
        var currentList = new List<int> {1, 2, 4, 7, 9};
    
        //get the missing items
        var missingItems = expectedRange.Except(currentList);       
    
        //print the missing items
        foreach (int missingItem in missingItems)
        {
            Console.WriteLine(missingItem);
        }
    
        Console.ReadLine();
    }
    

    Regards, y00daa

    0 讨论(0)
  • 2020-12-04 18:17
     int sum = 0,missingNumber;
            int[] arr = { 1,2,3,4,5,6,7,8,9};
            for (int i = 0; i < arr.Length; i++)
            {
                sum += arr[i];
            }
            Console.WriteLine("The sum from 1 to 10 is 55");
            Console.WriteLine("Sum is :" +sum);
            missingNumber =  55 - sum;
            Console.WriteLine("Missing Number is :-"+missingNumber);
            Console.ReadLine();
    
    0 讨论(0)
  • 2020-12-04 18:20
    var list = new List<int>(new[] { 1, 2, 4, 7, 9 });
    var result = Enumerable.Range(0, 10).Except(list);
    
    0 讨论(0)
  • 2020-12-04 18:25

    Create an array of num items

    const int numItems = 1000;
    bool found[numItems] = new bool[numItems];
    
    
    List<int> list;
    
    PopulateList(list);
    
    list.ForEach( i => found[i] = true );
    
    // now iterate found for the numbers found
    for(int count = 0; i < numItems; ++numItems){
      Console.WriteList("Item {0} is {1}", count, found[count] ? "there" : "not there");
    }
    
    0 讨论(0)
提交回复
热议问题