2010-11-07 17 views

Respuesta

16

Con LINQ:

int min = theArray.Min(); 

nota que esto va a error si no hay cualquier elementos; compruebe primero el .Length (o alternativamente, proyecte a int?, pero eso agrega sobrecarga).

Si usted no tiene LINQ disponibles, entonces tal vez:

public static int Min(int[] arr) { 
    switch (arr.Length) { 
     case 0: throw new InvalidOperationException(); 
     case 1: return arr[0]; 
     case 2: return Math.Min(arr[0], arr[1]); 
     default: 
      int min = arr[0]; 
      for (int i = 1; i < arr.Length; i++) { 
       if (arr[i] < min) min = arr[i]; 
      } 
      return min; 
    } 
} 
+0

¿qué significa? 'caso 2: devuelve Math.Min (arr [0], arr [1]);' ¿qué haces en default? –

+0

¿Qué significa? 'caso 1: return arr [0];'? –

+0

@SaeedAlg - Estoy comprobando la longitud de la matriz; si se trata de un ítem, entonces el min es obviamente el primer (único) ítem; si hay 2, entonces trátelo como otro caso especial * porque podemos hacerlo de manera conveniente *; de lo contrario, repetiremos sobre la matriz y * find * el mínimo –

1

escribí abajo para comparar lo que he dicho por @Marc Gravell, la manera en que yo dije es un poco más rápido en mi PC, y el LINQ es una manera más lenta, también si se cambia la posición de las funciones (en clave) que siempre va a obtener un mejor rendimiento con una versión con if

static void Main(string[] args) 
    { 
     Dictionary<string, List<long>> dic = new Dictionary<string, List<long>>(); 

     dic["First"] = new List<long>(); 
     dic["Second"] = new List<long>(); 
     dic["Third"] = new List<long>(); 


     for (int i = 0; i < 500; i++) 
     { 
      int[] array = GetRandomArray(); 
      Stopwatch stopWacth = new Stopwatch(); 
      stopWacth.Restart(); 
      int n1 = FindMin(array); 
      stopWacth.Stop(); 
      long firstTicks = stopWacth.ElapsedTicks; 
      dic["First"].Add(firstTicks); 

      stopWacth.Restart(); 
      int n2 = AnotherFindMin(array); 
      stopWacth.Stop(); 
      long secondTick = stopWacth.ElapsedTicks; 
      dic["Second"].Add(secondTick); 

      stopWacth.Restart(); 
      int n3 = array.Min(); 
      stopWacth.Stop(); 
      long thirdTick = stopWacth.ElapsedTicks; 
      dic["Third"].Add(thirdTick); 

      Console.WriteLine("first tick : {0}, second tick {1}, third tick {2} ", firstTicks, secondTick, thirdTick); 
     } 

     Console.WriteLine("first tick : {0}, second tick {1}, third tick {2} ", dic["First"].Average(), dic["Second"].Average(), dic["Third"].Average()); 

     Console.ReadLine(); 
    } 


    public static int[] GetRandomArray() 
    { 
     int[] retVal = new int[1000000]; 
     Random r = new Random(); 
     for (int i = 0; i < 1000000; i++) 
     { 
      retVal[i] = r.Next(1000000000); 
     } 
     return retVal; 
    } 

    public static int FindMin(int[] arr) 
    { 
     switch (arr.Length) 
     { 
      case 0: throw new InvalidOperationException(); 
      case 1: return arr[0]; 
      case 2: return Math.Min(arr[0], arr[1]); 
      default: 
       int min = arr[0]; 
       for (int i = 1; i < arr.Length; i++) 
       { 
        if (arr[i] < min) min = arr[i]; 
       } 
       return min; 
     } 
    } 

    public static int AnotherFindMin(int[] arr) 
    { 
     if (arr.Length > 0) 
     { 
      int min = arr[0]; 
      for (int i = 1; i < arr.Length; i++) 
      { 
       if (arr[i] < min) min = arr[i]; 
      } 
      return min; 
     } 
     else 
     { 
      throw new InvalidOperationException(); 
     } 
    } 
} 
// revised test by Marc (see comments discussion) 
static class Test { 
    static void Main(string[] args) 
    { 
     Dictionary<string, List<long>> dic = new Dictionary<string, List<long>>(); 

     dic["First"] = new List<long>(); 
     dic["Second"] = new List<long>(); 
     dic["Third"] = new List<long>(); 

     const int OUTER_LOOP = 500, INNER_LOOP = 500000; 
     for (int arrSize = 1; arrSize <= 3; arrSize++) 
     { 
      for (int i = 0; i < OUTER_LOOP; i++) 
      { 
       int[] array = GetRandomArray(arrSize); 
       Stopwatch stopWacth = Stopwatch.StartNew(); 
       for (int j = 0; j < INNER_LOOP; j++) 
       { 
        int n1 = FindMin(array); 
       } 
       stopWacth.Stop(); 
       long firstTicks = stopWacth.ElapsedTicks; 
       dic["First"].Add(firstTicks); 

       stopWacth = Stopwatch.StartNew(); 
       for (int j = 0; j < INNER_LOOP; j++) 
       { 
        int n2 = AnotherFindMin(array); 
       } 
       stopWacth.Stop(); 
       long secondTick = stopWacth.ElapsedTicks; 
       dic["Second"].Add(secondTick); 

       stopWacth = Stopwatch.StartNew(); 
       for (int j = 0; j < INNER_LOOP; j++) 
       { 
        int n3 = array.Min(); 
       } 
       stopWacth.Stop(); 
       long thirdTick = stopWacth.ElapsedTicks; 
       dic["Third"].Add(thirdTick); 

       //Console.WriteLine("{3}: switch : {0}, 0-check {1}, Enumerable.Min {2} ", firstTicks, secondTick, thirdTick, arrSize); 
      } 

      Console.WriteLine("{3}: switch : {0}, 0-check {1}, Enumerable.Min {2} ", dic["First"].Average(), dic["Second"].Average(), dic["Third"].Average(), arrSize); 
     } 
     Console.WriteLine("Done"); 
     Console.ReadLine(); 
    } 


    public static int[] GetRandomArray(int size) 
    { 
     int[] retVal = new int[size]; 
     Random r = new Random(); 
     for (int i = 0; i < retVal.Length; i++) 
     { 
      retVal[i] = r.Next(1000000000); 
     } 
     return retVal; 
    } 

    public static int FindMin(int[] arr) 
    { 
     switch (arr.Length) 
     { 
      case 0: throw new InvalidOperationException(); 
      case 1: return arr[0]; 
      case 2: return arr[0] < arr[1] ? arr[0] : arr[1]; 
      default: 
       int min = arr[0]; 
       for (int i = 1; i < arr.Length; i++) 
       { 
        if (arr[i] < min) min = arr[i]; 
       } 
       return min; 
     } 
    } 

    public static int AnotherFindMin(int[] arr) 
    { 
     if (arr.Length > 0) 
     { 
      int min = arr[0]; 
      for (int i = 1; i < arr.Length; i++) 
      { 
       if (arr[i] < min) min = arr[i]; 
      } 
      return min; 
     } 
     else 
     { 
      throw new InvalidOperationException(); 
     } 
    } 
} 
+1

Un 'Cronómetro' sobre una iteración única no dará una respuesta significativa; Además, esta prueba solo considera el caso 'predeterminado' (que para ser justos es el más probable). Y esa matriz es ** tan abrumadoramente grande que cualquier prueba * apenas muestra * ningún número de esta elección de lógica ... –

+0

@Marc Gravell, escribí que es –

+0

promedio @SaeedAlg - pero es un promedio de un número casi sin sentido ... –

Cuestiones relacionadas