2011-11-07 14 views
11

tengo esta misión cuando debo eliminar un elemento seleccionado de entre una gran variedad, por lo que me ocurrió con este código:Cómo eliminar un elemento elegido en el conjunto?

strInput = Console.ReadLine(); 
for (int i = 0; i < intAmount; i++) 
{ 
    if (strItems[i] == strInput) 
    { 
     strItems[i] = null; 
     for (int x = 0; x < intAmount-i; x++) 
     { 
      i = i + 1; 
      strItems[i - 1] = strItems[i]; 
     } 
     intAmount = intAmount - 1; 
    } 
} 

El problema es que, supongamos que tengo una serie [1,2,3,4,5,], y quiero eliminar 1 . La salida sería [2,3,4,5,5]. Esto también ocurre cuando elijo 2, pero no sucede cuando elijo otro número.

¿Qué estoy haciendo mal?

+2

¿Cuáles son '' intAmount' y strItems'? Está manipulando mucho sus índices for-loop dentro de sus bucles for, lo que generalmente es una mala idea. –

+0

Puede aclarar su pregunta: usted dice [1,2,3,4,5], con la operación para eliminar 1, se convierte en [2,3,4,5,5]. ¿Cómo eliges 5 como el elemento para duplicar al final? – ssamuel

+0

strItems es la matriz de cadenas, intAmount es la cantidad de elementos y strInput es el elemento que el usuario elige eliminar. – user1033065

Respuesta

33

Asumo que está trabajando con un conjunto básico de cuerdas:

var strItems = new string[] { "1", "2", "3", "4", "5" }; 

En .NET, esa matriz siempre va a ser de 5 elementos larga. Para eliminar un elemento, tendrá que copiar los elementos restantes en una nueva matriz y devolverlo. Establecer el valor en una posición a null no lo elimina de la matriz.

Ahora, con cosas como LINQ esto es muy fácil (no se muestra aquí), o se puede hacer trampa utilizando la colección List<> y hacer esto:

var list = new List<string>(strItems); 
list.Remove("3"); 
strItems = list.ToArray(); 

Pero no creo que va a enseñar cualquier cosa.

El primer paso es encontrar el índice del elemento que desea eliminar. Puede usar Array.IndexOf para ayudarlo. Vamos a buscar el elemento medio, "3":

int removeIndex = Array.IndexOf(strItems, "3"); 

Si no se encontró el elemento, devolverá un -1, a fin de comprobar de que antes de hacer nada.

if (removeIndex >= 0) 
{ 
    // continue... 
} 

Finalmente tiene que copiar los elementos (excepto el que está en el índice que no queremos) a una nueva matriz. Así, en total, se termina con algo como esto (comentado para la explicación):

string strInput = Console.ReadLine(); 
string[] strItems = new string[] { "1", "2", "3", "4", "5" }; 

int removeIndex = Array.IndexOf(strItems, strInput); 

if (removeIndex >= 0) 
{ 
    // declare and define a new array one element shorter than the old array 
    string[] newStrItems = new string[strItems.Length - 1]; 

    // loop from 0 to the length of the new array, with i being the position 
    // in the new array, and j being the position in the old array 
    for (int i = 0, j = 0; i < newStrItems.Length; i++, j++) 
    { 
     // if the index equals the one we want to remove, bump 
     // j up by one to "skip" the value in the original array 
     if (i == removeIndex) 
     { 
      j++; 
     } 

     // assign the good element from the original array to the 
     // new array at the appropriate position 
     newStrItems[i] = strItems[j]; 
    } 

    // overwrite the old array with the new one 
    strItems = newStrItems; 
} 

Y ahora strItems será la nueva matriz, menos el valor especificado para su eliminación.

+0

¡Guau! ¡Qué respuesta completa y explicativa! – zazkapulsk

1
  • Las matrices son de tamaño fijo, no se puede acortar su longitud sin crear una nueva matriz. Todo lo que puede hacer es almacenar la longitud de elementos válidos en la matriz (es decir, después de eliminar 1 la longitud es 4).

    Además, no estoy seguro de si el orden de los elementos en su matriz es importante, pero si no lo es podría cambiar los primeros y últimos elementos en lugar de mover cada elemento después del que se quitó 1 posición hacia adelante.

  • Una alternativa al uso de una matriz es utilizar una colección como ArrayList que se ocupará de cambiar el tamaño, eliminar y mantener un recuento de la cantidad de elementos en ella, y mucho más.

  • Sin embargo, dado que esta es la tarea, es posible que tenga que usar arreglos. Realice un seguimiento de la longitud con una variable, en lugar de utilizar array.length, o cree una nueva matriz cada vez que desee cambiar el tamaño.Si no tiene que usar arreglos, mire las colecciones que puede usar en C#.

3

matrices en C# son de un tamaño fijo - una vez inicializado sólo se puede modificar los elementos, pero no se puede agregar o quitar elementos. Si desea eliminar un elemento de una colección, tiene dos opciones:

1.) Cree una nueva matriz que tenga todos los miembros de la matriz original menos la que desea eliminar.

2.) Utilice un tipo de colección que se puede cambiar de tamaño y permite agregar o quitar elementos como List<T> (List<int> en su caso). Esto es lo que harías en el "mundo real" si tu colección no es estática.

3

En su implementación específica, creo que omite una instrucción break;, debe salir del bucle externo cuando termine el bucle interno. La asignación a null no es útil en absoluto.

Si la lista es solo una lista de números, ¿por qué usa cadenas? usa enteros directamente si es el caso.

Su ejercicio parece preguntar algo como esto, si necesita eliminar solo un elemento.

public bool MyDelete(int[] array, int value) // Easy to do for strings too. 
{ 
    bool found = false; 
    for (int i = 0; i < array.Length; ++i) 
    { 
     if (found) 
     { 
      array[i - 1] = array[i]; 
     } 
     else if (array[i] == value) 
     { 
      found = true; 
     } 
    } 
    return found; 
} 

Esta función devolverá verdadero si encuentra el error especificado, falso si no. Moverá todos los elementos como describe en su ejemplo, pero, por supuesto, no cambiará el tamaño de la matriz.

Las matrices son de tamaño fijo. No puede cambiar el tamaño de una matriz, simplemente, el idioma no lo permite. ¡Las matrices son, fueron y siempre serán de tamaño fijo!

Para eliminar un elemento de una matriz que debe hacer algo esto:

public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch. 
{ 
    int count = array.Length - 1; 
    T[] result = new T[count]; 

    if (index > 0) 
     Array.Copy(array, 0, result, 0, index - 1); 
    if (index < size) 
     Array.Copy(array, index + 1, result, index, size - index); 

    return result; 
} 

... 
strItems = RemoveAt(strItems, index); 

Esta función creará una nueva matriz que contiene todos los elementos excepto el que está en el índice que especifique.

Ahora, ¿por qué alguien haría algo como esto en vez de usar una lista o un diccionario o wathever? Use directamente una lista sin usar una matriz.

2

puede utilizar Excepto método para filtrar los datos

AllData = {10, 30, 20, 50} 

FilterData = {30, 20} 

Result = AllData.Except(​FilterData) 

resultado será {10, 50}

Cuestiones relacionadas