Jump to content

Funcion que organiza tablas


Recommended Posts

El script lo hize por que estaba aburrido y queria Proponorme un reto, Asi que me puse a crearlo y me cabe aclarar que este no es un metodo tan optimizado, el tiempo que tarda la funcion en organizar la tabla es de 0.1 segundo o mucho menos.

Si ves que algo esta de mas en la funcion o que te parece algo inutil... que la funcion lee demasiado codigo... que use muchos ciclos... Bla Bla Bla, Puedes ayudar a mejorar el código y tratar de no comentar tonterias.

La función retorna una tabla con los datos ya organizados, al último encontraras un ejemplo de como se usa esta función.

------------------------------------- 
--Proyecto:      Ninguno.
--Autor:         Rex.
--En Desarrollo: 3 Dias.
--Recurso:       Organizar una tabla.
-------------------------------------
 
function orderTable( Table, type_Order, limit )
 
    --Si el argumento Table no es una tabla entonces retornamos una tabla vacia
    if type ( Table ) ~= "table" then
        return { }
    end
 
    if type ( type_Order ) ~= "string" then
        return { }
    end
 
    if not limit then
        limit = #Table
    end
 
    if type ( limit ) ~= "number" then
        return { }
    end
 
    ---->Funciones utiles<----
 
    --Tabla de letras con su respectivo valor
    local wordOrderingTable =
    {
        { 'a', 1 },
        { 'b', 2 },
        { 'c', 3 },
        { 'd', 4 },
        { 'e', 5 },
        { 'f', 6 },
        { 'g', 7 },
        { 'h', 8 },
        { 'i', 9 },
        { 'j', 10 },
        { 'k', 11 },
        { 'l', 12 },
        { 'm', 13 },
        { 'n', 14 },
        { 'o', 15 },
        { 'p', 16 },
        { 'q', 17 },
        { 'r', 18 },
        { 's', 19 },
        { 't', 20 },
        { 'u', 21 },
        { 'v', 22 },
        { 'w', 23 },
        { 'x', 24 },
        { 'y', 25 },
        { 'z', 26 },
        { 'A', 1 },
    { 'B', 2 },
    { 'C', 3 },
    { 'D', 4 },
    { 'E', 5 },
    { 'F', 6 },
    { 'G', 7 },
    { 'H', 8 },
    { 'I', 9 },
    { 'J', 10 },
    { 'K', 11 },
    { 'L', 12 },
    { 'M', 13 },
    { 'N', 14 },
    { 'O', 15 },
    { 'P', 16 },
    { 'Q', 17 },
    { 'R', 18 },
    { 'S', 19 },
    { 'T', 20 },
    { 'U', 21 },
    { 'V', 22 },
    { 'W', 23 },
    { 'X', 24 },
    { 'Y', 25 },
    { 'Z', 26 },
    }
 
    --Función que permite obtener el tipo de indexado de la tabla
    local function typeIndex( Table )
        local tipoIndexado = false
        for _, v in ipairs( Table ) do
            if type( v ) ~= "table" then
                tipoIndexado = true
                break
            end
        end
        return tipoIndexado
    end 
 
    --Función que permite obtener el numero mas alto de una tabla
    local function getMaxNumberTable( Table )
 
        local contador = 1
        local finalCiclo = #Table+1
        local numeroMasAlto = 1
        while contador < finalCiclo do
 
            local tipoIndexado = typeIndex( Table )
            local dato
 
            if tipoIndexado == true then
                dato = Table[contador]
            else
                dato = Table[contador][1]
            end
 
            for _, value in ipairs( Table ) do
 
                local valorTabla
                if tipoIndexado == true then
                    valorTabla = value
                else
                    valorTabla = value[1]
                end
 
                if dato > valorTabla then
                    if numeroMasAlto < dato then
                        numeroMasAlto = dato
                    end
                end
 
            end
            contador = contador + 1
        end
        return numeroMasAlto
    end
 
    --Identificamos el tipo de indexado de la tabla
    local firstConstant
    local tipoIndexado = typeIndex ( Table )
    if tipoIndexado == true then
        firstConstant = Table[1]
    else
        firstConstant = Table[1][1]
    end
   
    local typeOfTable
    --Analizando el primer dato y identificamos si es un numero o una tabla con palabras
    if type ( tonumber( firstConstant ) ) == "number" then
        typeOfTable = "numbers"
    elseif type ( firstConstant ) == "string" then
        typeOfTable = "words"
    end
 
    if typeOfTable then
 
        --Se ordenara la tabla segun el tipo de orden dada desde el argumento type_Order ( Asc o Desc )
        if typeOfTable == "numbers" then
 
            local tablaOrganizada = { }
 
            if type_Order == "Asc" then
 
                --obtenemos el numero mayor de la tabla, para que el ciclo se repita hasta ese numero
                local numeroMasAlto = getMaxNumberTable ( Table )
                local posicionesOrganizadas = 1
                while posicionesOrganizadas < numeroMasAlto+1 do
 
                    --Detenemos el bucle cuando se haya llegado al limite
                    if posicionesOrganizadas > limit+1 then
                        break
                    end
 
                    for i, v in ipairs( Table ) do
 
                        local tipoIndexado = typeIndex ( Table )
 
                        if tipoIndexado == true then
 
                            if posicionesOrganizadas == v then
                                table.insert( tablaOrganizada, v )
                            end
                        else
                            if posicionesOrganizadas == v[1] then
                                table.insert( tablaOrganizada, { v[1] } )
                            end
                        end
                    end
                    posicionesOrganizadas = posicionesOrganizadas + 1
                end
 
            elseif type_Order == "Desc" then
 
                --obtenemos el numero mayor de la tabla, para que el ciclo se repita
                --hasta que el valor alamacenado en la variable 'posicionesOrganizadas' llege a 1.
                local posicionesOrganizadas = getMaxNumberTable ( Table )
                local contadorLimite = 0
                while posicionesOrganizadas >= 1 do
                   
                    if contadorLimite >= limit then break end
 
                    for i, v in ipairs( Table ) do
 
                        local tipoIndexado = typeIndex ( Table )
 
                        if tipoIndexado == true then
 
                            if posicionesOrganizadas == v then
                                table.insert( tablaOrganizada, v )
                                contadorLimite = contadorLimite + 1
                            end
                        else
                            if posicionesOrganizadas == v[1] then
                                contadorLimite = contadorLimite + 1
                                table.insert( tablaOrganizada, { v[1] } )
                            end
                        end
                    end
                    posicionesOrganizadas = posicionesOrganizadas - 1
                end
            end
 
            return tablaOrganizada
        elseif typeOfTable == "words" then
 
                local temporalyTable = { }
                local contadorT = 0
                for i, v in ipairs( Table ) do
 
                    local palabra
                    local palabraNoSub
                    local tipoIndexado = typeIndex ( Table )
                    if tipoIndexado == true then
                        palabra = v
                        palabraNoSub = v
                    else
                        palabra = v[1]
                        palabraNoSub = v[1]
                    end
 
                    --Transformamos las letras a numeros para ser organizadas
                    for _, value in ipairs( wordOrderingTable ) do
 
                        local wordF, totalValue = value[1], value[2]   
                        palabra = string.gsub( palabra, wordF, totalValue )
                           
                    end
 
                    contadorT = contadorT + 1
 
                    if contadorT > limit then break end
 
                   
Edited by Guest
Link to comment
¿Qué printea exactamente?

En las ultimas lineas esta un ejemplo.

Ves una tabla con números del 1 al 10 puestos en forma Ascendente y usando la función con el tipo de organizacion "Desc" este printea la tabla de forma descendente, No solo puedes hacerlo con números también con palabras, También después del argumento de tipo de organización, puedes establecer un límite ( Así como en sql )

Ejemplo:

orderTable ( tabla, tipo_organización [ "Desc" o "Asc"], limite )

--De esta forma retona una tabla con los datos organizados de la tabla "tabla" de forma Ascendente y con un limite de 3 ( Los que han usando SQLite Entenderán )

orderTable ( tabla, "Asc", 3 )

--De esta forma retorna una tabla organizada de forma Descendente.

orderTable ( tabla, "Desc", 3 )

--De esta forma retorna una tabla organizada de forma Ascendente sin limite

orderTable ( tabla, "Asc" )

Si pone a una tabla que esta de esta forma:

local table5 = {

{ dato },

}

Te retorna una tabla de la misma forma.

Si pones una tabla de esta forma:

local table5 = {

"a",

"b",

}

Te la retorna la tabla de la misma forma.

Hay te he hecho mas detalladamente como funciona.

Link to comment
  • 2 weeks later...

Es recurrente el tema de ordenamiento en programación, pero nose si sabes que en lua existe el método sort para ordenar tablas. Aquí el link https://www.lua.org/pil/19.3.html.

Ahora cual es el sentido de hacer funciones propias para ordenar? Se supone que estas funciones te sirven para ordenar pero tu trabajo es hacer una con la que puedas ordenar mas optima-mente tu data. Por lo que se sabe la forma mas optima de ordenar es logaritmicamente insertando data en forma de arbol (si mal no recuerdo). Ahora si tu inserción de datos es lineal es muy poco optima.

Compara tu función con sort en tiempos de ejecución, ve cual es mas optima y nos comentas ;)

Link to comment

Si sabia que existía el método sort, Pero para mi esa función como que no la entendía del todo y habia visto el post de ASuS ( Visualizaciones ) y Dije, Why not? Recreare esa función.

En eso de forma de arbol no se a que te refieres, mis conocimientos En lógica son muy pocos, Me vendría muy bien que me muestrea como funciona eso.

Link to comment

No se si sabes que ordenar datos sirve para una búsqueda mas eficiente, existe un método llamado búsqueda binaria que es uno de los mas eficientes ya que tiene complejidad logarítmica. Es decir encuentra un dato en log2(n) en cambio un metodo de busqueda lineal tiene complejidad n. Lo que claramente es una gran diferencia.

Te dejo un link de como funciona la inserción de datos en un árbol binario:

Link to comment

Hmmm, me interesado por el tema este.. acabo de mirar el vídeo pero no me quedo del toco claro por que de esta manera es mucho mas eficiente que otras? es decir lo que hace básicamente es si un numero es mayor o menor del otro lo pone en una parte o otra pero sinceramente no me quedo muy claro porque?

Edito: Estuve haciendo unas pruebas con esto y bien, puede que sea bastante rápido el sort.

El codigo con el que he probado es:

function swap(items, firstIndex, secondIndex) 
    local temp = items[firstIndex] 
    items[firstIndex] = items[secondIndex] 
    items[secondIndex] = temp 
end 
  
  
  
function partition(items, left, right) 
  
    local pivot   = items[math.floor((right + left) / 2)]; 
    local i = left; 
    local j = right; 
  
  
    while (i <= j) do 
  
        while (items[i] < pivot) do 
            i = i + 1; 
        end 
  
        while (items[j] > pivot) do 
            j = j - 1; 
        end 
  
        if (i <= j) then 
            swap(items, i, j); 
            i = i + 1; 
             j = j - 1; 
        end 
    end 
  
    return i; 
end 
  
function quickSort(items, left, right) 
  
    local  index; 
  
    if (#items > 1) then 
  
        local left = type(left) ~= "number" and 1 or left; 
        local right = type(right) ~= "number" and #items or right; 
  
        index = partition(items, left, right); 
  
        if (left < index - 1) then 
            quickSort(items, left, index - 1); 
        end 
  
        if (index < right) then 
            quickSort(items, index, right); 
        end 
  
    end 
  
    return items; 
end 

Que es básicamente el quicksort y he obtenido una velocidad 135 Milisegundos ordenando una tabla de 50.000 números entre el 0 y el 200000000000000

La cosa esta en que este método es solo útil para organizar arrays de números al igual que el ejemplo que has puesto tu de Binary Tree si no me equivoco, si se puede me gustaría saber como?

Link to comment
Hmmm, me interesado por el tema este.. acabo de mirar el vídeo pero no me quedo del toco claro por que de esta manera es mucho mas eficiente que otras? es decir lo que hace básicamente es si un numero es mayor o menor del otro lo pone en una parte o otra pero sinceramente no me quedo muy claro porque?

Edito: Estuve haciendo unas pruebas con esto y bien, puede que sea bastante rápido el sort.

El codigo con el que he probado es:

function swap(items, firstIndex, secondIndex) 
    local temp = items[firstIndex] 
    items[firstIndex] = items[secondIndex] 
    items[secondIndex] = temp 
end 
  
  
  
  
function partition(items, left, right) 
  
    local pivot   = items[math.floor((right + left) / 2)]; 
    local i = left; 
    local j = right; 
  
  
    while (i <= j) do 
  
        while (items[i] < pivot) do 
            i = i + 1; 
        end 
  
        while (items[j] > pivot) do 
            j = j - 1; 
        end 
  
        if (i <= j) then 
            swap(items, i, j); 
            i = i + 1; 
             j = j - 1; 
        end 
    end 
  
    return i; 
end 
  
function quickSort(items, left, right) 
  
    local  index; 
  
    if (#items > 1) then 
  
        local left = type(left) ~= "number" and 1 or left; 
        local right = type(right) ~= "number" and #items or right; 
  
        index = partition(items, left, right); 
  
        if (left < index - 1) then 
            quickSort(items, left, index - 1); 
        end 
  
        if (index < right) then 
            quickSort(items, index, right); 
        end 
  
    end 
  
    return items; 
end 

Que es básicamente el quicksort y he obtenido una velocidad 135 Milisegundos ordenando una tabla de 50.000 números entre el 0 y el 200000000000000

La cosa esta en que este método es solo útil para organizar arrays de números al igual que el ejemplo que has puesto tu de Binary Tree si no me equivoco, si se puede me gustaría saber como?

Compáralo con el sort de esta pagina: https://www.lua.org/pil/19.3.html

Es un método de lua así que úsalo con confianza xD

Link to comment
Acabo de probarlo y eh recibido valores bastante inferiores 100 Milisegundos mas rápido.

Ahora si que no comprendo por que dices que ese método es mas rápido?

Yo dije que el reto esta en encontrar un metodo mas rapido xD

Lo mas rapido es no ordenar sino insertar los datos de manera ordenada. Para cuando realices una busqueda o consulta por busqueda binaria, encontrar el dato mas rapido.

Link to comment

Pero, cuando tu necesitas ordenar una tabla para que luego puedas ya sea controlarla o hacerle cualquier cosa este método es bastante lento por lo que estoy viendo. A lo mejor en otros lenguajes como C++ este método de sort es mucho mas rápido pero en LUA parece que no.

Link to comment
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...