Ayuda con ordenamiento de vector

Iniciado por josezamp, 30 Octubre 2014, 13:33 PM

0 Miembros y 1 Visitante están viendo este tema.

josezamp

Hola gente! Estoy desarrollando un código que tiene el siguiente enunciado:

a) Sumar los elementos de un vector.
b) Devolver si un número ingresado es positivo, negativo o cero.
c) Ordenar los elementos de una matriz en forma ascendente.
Utilizar procedimientos y funciones para realizar los incisos a, b y c. Todos los resultados deben imprimirse en el programa principal.


Por lo que mi código va quedando de la siguiente manera:
Código (vbnet) [Seleccionar]
Module Module1

   Sub Main()
       Dim vector(5, 2) As String ' declaro la matriz
       Dim suma As Integer
       Call valores(vector, suma)
       For i = 1 To 5
           Console.WriteLine("Valor ingresado en el vector {0} = {1} y es {2}", i, vector(i, 1), vector(i, 2))
       Next
       Console.WriteLine("Suma de los valores ingresados: {0}", suma)
       Console.ReadLine()
   End Sub
   Sub valores(ByRef vector, ByRef suma)
       suma = 0
       For i = 1 To 5
           Console.Write("Escriba el valor para el vector {0}º: ", i)
           vector(i, 1) = Console.ReadLine ' ingreso los valores para la matriz
           Select Case vector(i, 1)
               Case Is < 0
                   vector(i, 2) = "menor que cero"
               Case Is > 0
                   vector(i, 2) = "mayor que cero"
               Case Is = 0
                   vector(i, 2) = "igual a cero"
           End Select
       Next
       For i = 1 To 5
           suma = suma + vector(i, 1) ' sumo los elementos del vector
       Next

   End Sub

End Module

Pero no sé qué método utilizar para que el programa ordene la matriz en forma ascendente ¿Algún consejo?
Desde ya, gracias  :)

Eleкtro

#1
¿Es explicitamente necesario usar un array 2D para el ejercicio?, lo comento porque personalmente no apoyo el uso de los array multi-dimensionales en VB.Net ya que realmente un array multi-dimensional no está soportado por la infraestructura de VB.NET (sin ir más lejos ni siquiera los soporta los métodos de la Class Array), en su defecto deberías usar un Array que contenga como elementos otros arrays uni-dimensionales, es decir, un 'Jagged Array' (dim arr()() as Integer) y el ordenamiento sería mucho más sencillo, pero en este caso específico deberías olvidarte de eso ya que lo mejor que deberías hacer es crear tu propio objeto para añadir los datos y usarlo en un array uni-dimensional.

Además, implementar la interface IComparer para comparar/ordenar con ese array 2D que tienes con dos datatypes diferentes (integer, string) resulta algo tedioso engorroso.

Y aparte, los índices en .NET empiezan por 0, no por 1, estás dejando elementos vacios y si te acostumbras a eso provocarás errores en tiempo de ejecución al intentar acceder a esos elementos vacios en el futuro.

Podría haberte escrito un ejemplo utilizando Arrays multi-dimensionales o Array de arrays (Jagged Array) pero ya que me pongo a escribir he preferido hacerlo utilizando el modo que considero más óptimo y esperando que no te sea completamente necesario la utilización de Array 2D, espero que te sirva.

Puedes adaptar el código a tus necesidades:

Código (vbnet) [Seleccionar]
Public NotInheritable Class MyData : Implements IComparable(Of MyData)

   ''' <summary>
   ''' </summary>
   Public Property Index As Integer

   ''' <summary>
   ''' </summary>
   Public Property Value As Integer

   ''' <summary>
   ''' </summary>
   Public Property Condition As String

   ''' <summary>
   ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/system.icomparable.compareto%28v=vs.110%29.aspx
   ''' Compares the current instance with another object of the same type
   ''' and returns an integer that indicates whether the current instance precedes,
   ''' follows, or occurs in the same position in the sort order as the other object.
   ''' </summary>
   ''' <param name="obj">An object to compare with this instance.</param>
   ''' <returns> A value that indicates the relative order of the objects being compared.</returns>
   Public Overloads Function CompareTo(ByVal obj As MyData) As Integer _
   Implements IComparable(Of MyData).CompareTo

       Return Value.CompareTo(obj.Value)

   End Function

End Class


Código (vbnet) [Seleccionar]
Module Module1

   ''' <summary>
   ''' Defines the entry point of the application.
   ''' </summary>
   Friend Sub Main()

       Dim data() As MyData = AddData(4)

       ' Unsorted
       PrintData(data)
       Console.ReadKey()

       ' Sorted
       Array.Sort(data)
       PrintData(data)
       Console.ReadKey()

   End Sub

   ''' <summary>
   ''' Adds the data.
   ''' </summary>
   ''' <param name="count">The item count to create.</param>
   Public Function AddData(ByVal count As Integer) As MyData()

       If count <= 0 Then
           Throw New ArgumentException("Parameter value can't be zero or negative", "count")
           Return Nothing
       End If

       Dim data(count) As MyData
       Dim value As Integer
       Dim condition As String

       For index As Integer = 0 To count

           Console.Write(String.Format("Escriba el valor para el vector {0}º: ",
                                       CStr(index)))

           Try
               value = Console.ReadLine

           Catch ex As Exception
               Throw

           End Try

           Select Case value

               Case Is < 0
                   condition = "menor que cero"

               Case Is > 0
                   condition = "mayor que cero"

               Case Else ' Is = 0
                   condition = "igual a cero"

           End Select

           data(index) = New MyData With
                             {
                               .Index = index,
                               .Value = value,
                               .Condition = condition
                             }

       Next index

       Return data

   End Function

   ''' <summary>
   ''' Prints the data.
   ''' </summary>
   ''' <param name="data">The data.</param>
   Private Sub PrintData(ByVal data() As MyData)

       Dim sum As Integer =
           (From item As MyData In data
            Select item.Value).Sum

       For Each item As MyData In data

           Console.WriteLine(String.Format("Valor ingresado en el vector {0} = {1} y es {2}",
                                           CStr(item.Index), CStr(item.Value), item.Condition))

       Next item

       Console.WriteLine(String.Format("Suma de los valores ingresados: {0}",
                                       CStr(sum)))

   End Sub

End Module







EDITO:
He escrito este ejemplo para demostrarte como lo podrías hacer con un Array 2D, está un poco hardcodeado... no es de uso genérico, y no te recomiendo usar este método ya que un Array 2D no es el "Contenedor" más apropiado para tus intenciones, siempre hay que buscar el Type/Contenedor más adecuado para cada situación...

Código (vbnet) [Seleccionar]
Class CustomArrayComparer : Implements IComparer

    ' Maintain a reference to the 2D array being sorted.
    Private sortedArray(,) As String

    Public Sub New(ByVal array(,))
        sortedArray = array
    End Sub

    ''' <summary>
    ''' Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
    ''' </summary>
    ''' <param name="x">The first object to compare.</param>
    ''' <param name="y">The second object to compare.</param>
    ''' <returns>
    ''' A signed integer that indicates the relative values of <paramref name="x"/> and <paramref name="y"/>,
    ''' </returns>
    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
    Implements IComparer.Compare

        ' x and y are integer row numbers into the sortArray
        Dim i1 As Integer = DirectCast(x, Integer)
        Dim i2 As Integer = DirectCast(y, Integer)

        ' compare the items in the sortArray
        Return sortedArray(i1, 0).CompareTo(sortedArray(i2, 0))

    End Function

End Class


Código (vbnet) [Seleccionar]
Module Module1

    ''' <summary>
    ''' Defines the entry point of the application.
    ''' </summary>
    Friend Sub Main()

        Dim data(,) As String = AddData(Of String)(4, 1)

        ' Unsorted
        PrintData(data) : Console.ReadKey()

        ' Sorted
        PrintDataSorted(data) : Console.ReadKey()

    End Sub

    ''' <summary>
    ''' Adds the data.
    ''' </summary>
    Public Function AddData(Of T)(ByVal d1Size As Integer,
                                  ByVal d2Size As Integer) As T(,)

        If d1Size <= 0 Then
            Throw New ArgumentException("Parameter value can't be zero or negative", "d1Size")
            Return Nothing

        ElseIf d2Size <= 0 Then
            Throw New ArgumentException("Parameter value can't be zero or negative", "d2Size")
            Return Nothing

        End If

        Dim data(d1Size, d2Size) As T ' As String
        Dim value As Integer
        Dim condition As T

        For index As Integer = 0 To d1Size

            Console.Write(String.Format("Escriba el valor para el vector {0}º: ",
                                        CStr(index)))

            Try
                value = CInt(Console.ReadLine)

            Catch ex As Exception
                Throw

            End Try

            Select Case value

                Case Is < 0
                    condition = CType(CObj("menor que cero"), T)

                Case Is > 0
                    condition = CType(CObj("mayor que cero"), T)

                Case Else ' Is = 0
                    condition =CType(CObj("igual a cero"), T)

            End Select

            data(index, 0) = CType(CObj(value), T)
            data(index, 1) = CType(CObj(condition), T)

        Next index

        Return data

    End Function

    ''' <summary>
    ''' Prints the data.
    ''' </summary>
    Private Sub PrintData(Of T)(ByVal data As T(,))

        Dim sum As Integer

        For index As Integer = 0 To (data.GetLength(0) - 1)

            Dim value As Integer = Convert.ToInt32(data(index, 0))
            Dim condition As String = Convert.ToString(data(index, 1))
            sum += value

            Console.WriteLine(String.Format("Valor ingresado en el vector {0} = {1} y es {2}",
                                            CStr(index), CStr(value), condition))

        Next index

        Console.WriteLine(String.Format("Suma de los valores ingresados: {0}",
                                        CStr(sum)))

    End Sub

    ''' <summary>
    ''' Prints the data sorted.
    ''' </summary>
    Private Sub PrintDataSorted(Of T)(ByVal data As T(,))

        Dim sum As Integer

        Dim taggedArray() As Integer =
            (From value As Integer
             In Enumerable.Range(0, data.GetLength(0))
             Select value).ToArray

        ' Initialize the comparer and sort
        Dim myComparer As New CustomArrayComparer(data)
        Array.Sort(taggedArray, myComparer)

        For index As Integer = 0 To (taggedArray.Length - 1)

            Dim value As Integer = Convert.ToInt32(data(taggedArray(index), 0))
            Dim condition As String = Convert.ToString(data(taggedArray(index), 1))
            sum += value

            Console.WriteLine(String.Format("Valor ingresado en el vector {0} = {1} y es {2}",
                                            CStr(index), CStr(value), condition))

        Next index

        Console.WriteLine(String.Format("Suma de los valores ingresados: {0}",
                                        CStr(sum)))

    End Sub

End Module


Saludos








Senior++

El ejercicio C, lo puedes hacer con el método burbuja, es decir funciona de la siguiente manera...

Arreglo:
Posicion 0 --> 20
Posicion 1 ---> 30
posicion 3 ---> 15

Si posicion 0 es mas CHICO que posicion 0+1
{
creas una variable auxiliar que sea igual a posicion 0
posicion 0 = posicion 0 + 1
posicion 0+1 = auxiliar

}

Tampoco te aconsejo que tengas valores fijos en los vectores, es decir que sean random o ingresados por el usuario, es decir puedes utilizar:

Console.writeline("Ingresa un numero");
int numeroIngresado = int.parse(Console.readLine()); // Analiza lo que esta dentro del paréntesis y lo convierte a entero

El valor que te genere lo guardas en un arreglo de tipo entero de X dimensiones
Vendo cuenta de LEAGUE OF LEGENDS lvl 30, EU west, muy barata