Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Serapis

#2971
La partición que haces es la original de Hoare, con la excepción de que Hoare, toma para el caso como pivot, el valor el índice minimo (el parámetro que tu llamas izq). En implementaciones más óptimas se suele tomar como pivot el índice central del rango presente.

El caso es que la partición es ciega, es decir, ni sabe que valores contiene, ni sabe donde está el menor ni el mayor, ni guarda información al respecto.
La partición simplemente divide hacia un lado u otro del pivot los valores mayores o menores del pivot, respectivamente. ...pero solo de los valores en el rango izq-der que recibe el array. No sabes en qué momento el valor késimo está en su sitio, solo tienes garantía de que al terminar de ordenar si lo estará.

Pero es que además, la partición para funcionar y evolucionar en las siguientes fases, DEBE forzosamente intercambiar valores, luego el algoritmo Quicksort se está ejecutando y por ende, el array se está ordenando, te guste o no.

En resumen, así opera el algoritmo QuickSort de Hoare...

Funcion QuicksortHoare(array Ar(), entero Min, entero Max)
   entero p
   
   si (Min < Max) luego
       p = ParticionHoare(Ar, Min, Max)
       llamada QuicksortHoare(Ar, Min, p)
       llamada QuicksortHoare(Ar, p + 1, Max)
   fin si
fin funcion

entero Funcion ParticionHoare(array Ar(), entero Min, entero Max)
   entero j, k, i, pivot

   pivot = Ar(Min)
   j = (Min - 1)
   k = (Max + 1)
   
   Hacer
       Hacer
           j = (j + 1)
       Repetir Mientras  (Ar(j) < pivot)
       Hacer
           k = (k - 1)
       Repetir Mientras (Ar(k) > pivot)
     
       si (j < k) luego
           i = Ar(j)
           Ar(j) = Ar(k)
           Ar(k) = i
       Sino
           devolver k
       Fin si
   Repetir
Fin Funcion


...y no hay forma de saber* en qué llamada tendrás el késimo valor ordenado en su sitio, excepto al término.

Por ejemplo, aquí un ejemplo, la primera línea es el array desordenado, las siguientes, son el array parcial en la siguiente etapa (he despreciado las etapas donde no cambia nada, para que quede lo más breve posible).
4 1 7 10 5 2 6 0 7 9
-----------------------
0 1 7 10 5 2 6 4 7 9
0 1 2 10 5 7 6 4 7 9
0 1 2
10 5 7 6 4 7 9
9 5 7 6 4 7 10
9 5 7 6 4 7
7 5 7 6 4 9
7 5 7 6 4
4 5 7 6 7
4 5 6 7 7
4 5 6
5 6
7 7

Aunque QuickSort sea muy eficiente, no es una búsqueda binaria (incluso a pesar de que en cierto modo haga particiones binarias), y por tanto no hay información precisa de dónde se haya el késimo valor que resultará ordenado hasta que no termine de ordenarse.
Si lo entiendes o no, es otra historia...



p.d.:
*: Aunque añadas código intermedio para intentar excrutarlo, será del todo ineficiente. Pués basta saber que con recorrer 1 sola vez el array obtienes el menor, para hallar el kesimo te basta recorrerlo k veces y si k es más de la mitad del tamaño, lo buscas desde el mayor hacia atrás. En realidad si k es un valor alto, será más ineficiente que ordenar el array.

Un modo mejor para lograr lo que quieres que con el procedimiento de Selection (que busca el menor en el array, sobre los n elementos no ordenados aún), es operar con grupos de tamaño k. entre sí, es decir si k = 5, ordena el array de 5 en 5 (supongamos 40 elementos); del 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39
Tras ese ordenamiento de los 8 grupos, se trata de hacer otra fase donde se procede a ordenar nuevamente (pero ahora por refundición puesto que ya están pre ordenados), cada dos grupos entre sí, y tras esta primera fase ya puedes descartar del 5-9, 15-19, 25-29, 35-39 (por que los 5 menores de cada grupo 5+5), se han movido al grupo de abajo), luego se sigue refundiendo otros grupos, pero saltanto los excluídos, así se refunde ahora: 0-4 con 10-14, 20-24 con 30-34. igualmente en cada etapa se van descartando la mitad de los elementos con los que se ha operado.
En esa última refundición será el grupo: 0-4 con 20-24 (los 5 menores se dejarán en 0-4, descartando finalmente también el grupo 20-24).
En la última refundición ya tendríamos 0-4 como menores, luego la solución sería miArray(4) (ya que dijimos que k=5)...

Esta solución también va particionando el array en 2, pero de cada vez deshecha (ordenar) la mitad (de los que quedan) que no contiene los deseados. Este método es incluso más óptimo para buscar el késimo elemento (que resultaría una vez ordenado) que por cualquier otro método donde el array no esté ya ordenado.



p.d2: Te pongo un ejemplo desarollado y comentado con éste último método... Si no eres capaz se implementarlo lo señalas y veo de sacar un tiempito y te oriento

El késimo pedido vamos a suponer que es el 5º (k=5), y supongamos el siguiente array aleatorio (de 40 elementos, 8 grupos, por simplicidad al no tener que lidiar con elementos sueltos, ...el propósito es que lo enttiendas):
16 11 12 14 13 20 31 32 42 26 17 28 4 25 15 6 11 2 29 5 8 32 21 25 37 41 1 7 40 30 35 11 0 22 34 3 19 43 38 27
El array separado en grupos de k (k=5 hemos puesto de ejemplo), solo por claridad...
16 11 12 14 13 || 20 31 32 42 26 || 17 28 4 25 15 || 6 11 2 29 5 || 8 32 21 25 37 || 41 1 7 40 30 || 35 11 0 22 34 || 3 19 43 38 27
Ordenando en la priemra fase (cada grupo de k entre sí). Ésta es una fase de ordenamiento previa, usando cualquier algoritmo de ordenamiento, cuando hay muy pocos elementos el más efectivo suele ser InsertionSort):
11 12 13 14 16 || 20 26 31 32 42 || 4 15 17 25 28 || 2 5 6 11 29 || 8 21 25 32 37 || 1 7 30 40 41 || 0 11 22 34 35 || 3 19 27 38 43
Refundimos gada dos grupos de 5 entre sí (y luego tachamos el segundo grupo que ya no se usará en la siguiente etapa):
11 12 13 14 16 || 20 26 31 32 42 || 2 4 5 6 11 || 15 17 25 28 29 || 1 7 8 21 25 || 32 37 30 40 41 || 0 3 11 19 22 || 34 35 27 38 43
En la siguiente, se refunden (y se muestrasn ya refundidos) los k elementos de dos grupos separados ahora por el doble de distancia previa (y tras los tachados de antes, se añade otro grupo de tachados)
2 4 5 6 11 || 20 26 31 32 42 || 12 13 14 16 11 || 15 17 25 28 29 || 0 1 3 7 8 || 32 37 30 40 41 || 21 25 11 19 22 || 34 35 27 38 43  
Finalmente solo quedan 2 grupos por refundir, se queda el bajo y se tacha el alto, con lo cual ya terminamos:
0 1 2 3 4 || 20 26 31 32 42 || 12 13 14 16 11 || 15 17 25 28 29 || 5 6 11 7 8 || 32 37 30 40 41 || 21 25 11 19 22 || 34 35 27 38 43
Y así el késimo será: Ar(k-1) = 4

Nota que segundo grupo tras la refundición no permanece ordenado (como se ve en:  5 6 11 7 8 ), una vez obtenido los k elementos en el 1º grupo, se pasa al segundo los que estaban en el 1º grupo remplazados por los del 2º... y se pasan para mantener la integridad del array (que siga teniendo los mismos elementos a la salida que contenía a la entrada).
#2972
Programación General / Re: metodo y funcion
10 Noviembre 2017, 17:01 PM
Técnicamente es lo mismo.

Desde un punto de vista más estricto y para comprenderlo, digamos que:
- La función deriva de la idea matemática: f = a_algo, es decir que hace algunas operaciones (que no nos importan) pero devuelve un resultado, que es lo que nos importa.
 por ejemplo, hallar lo que mide un círculo dado su radio:
 m = circulo.MedirPerimetro(Radio), que simplemente dice que m= (2 * pi * radio)
- El método es la idea práctica de: resolver algo, hacer alguna cosa, en ese sentido, se supone que se dan ciertos pasos en un orden concreto, para llevarlo a cabo.
 Por ejemplo ordenar un array: array.Sort(miArray)

En la prácitca son indistinguibles, no hay importancia, nada notable salvo la preferencia personal o incluso que en muchos entornos tienen preferencia por un término u otro. Es común referirse a las procedimientos que posee un objeto como métodos, que se toma como algo más genérico que función. En parte porque muchos tenemos un concepto de 'función matemática', muy arraigado al punto de que se cree conveniento hacer notar una diferencia pero que en realidad no existe como tal.

Incluso la misma wikipedia, aunque recoge un artículo para cada cuestión, adecuadamente se declara una nulidad entre diferencias...
función: https://es.wikipedia.org/wiki/Subrutina
método: https://es.wikipedia.org/wiki/Método_(informática)

#2973
La cacareada 'inteligencia artificial' aún está en pañales.
¿Dejarías algo en manos de un  niño de 2 años?. Pués un niño de 2 años supera en inteligencia a las inteligencias artificiales actuales (síiii, en velocidad y cálculo siempre irán muy por delante, pero eso no es inteligencia artificial). ...además es relativamente fácil trolear a dicha inteligencia artificial, y si lo es por parte de los usuarios (ya se ha demostrado en varias ocasiones), también prodría serlo hackeándolo...
#2974
Ya, pero es que si usas QuickSort, ya estás ordenando el array, porque Si o Sí debe hacer intercambios.
Entonces que al final no esté completamente ordenado el array, porque queden algunos intercambios por hacer, es trivial... (quedaría completamente ordenado si te pidieran el elemento 0º)

Con la parte primera del enunciado, sin el asunto de QuickSort, puedes solventarlo así (sería equivalente al procedimiento para un ordenamiento SelectionSort):


entero = BuscarKEsimo(entero ksimo, array Ar())
    entero menor

    // 1º: Buscar el mnor del array
    menor = BuscarMenor(ar, 0, ar.count -1)

    // 2º buscar el que sigue al menor hallado hasta el momento.
    bucle para k desde 1 hasta ksimo  //se supone que ksimo está dentro de los límites del array.
        menor = BuscarMenorSiguiente(ar, 0, ar.count-1, menor)
    fin bucle
    devolver menor
fin funcion

// Esta función busca el menor en un array.
entero = funcion BuscarMenor(array Ar(), entero desde, entero hasta)
    entero v
   
    v = ar(desde)
    Hacer mientras (desde <= hasta)
        Si (Ar(desde) < v) luego
            v = Ar(desde)
        fin si
        desde += 1
    repetir
   
    devolver = v
fin funcion

// esta función busca el menor en un array mayor que 'exige'.
entero = funcion BuscarMenorSiguiente(array Ar(), entero desde, entero hasta, entero exige)
    entero v
   
    v = ar(desde)
    Hacer mientras (desde <= hasta)
        Si (( Ar(desde) < v) y ( Ar(desde) > exige)) luego  // esta es la diferencia de la función previa: y ( Ar(desde) > exige)
            v = Ar(desde)
        fin si
        desde += 1
    repetir
   
    devolver = v
fin funcion


Nota: Que si el array tiene elementos repetidos (para el valor que se pide o anterior), no lo resuelve, queda a tu esfuerzo solucionarlo, así como pasar el pseudocódigo al lenguaje deseado.

#2975
Muy bien, pero no aclara en qué países se impondrá dichas leyes.

Bueno sería, que fuera consensuado en todo el planeta, aunque luego sabemos que cada cual hará lo que le venga en gana, porque una vez en su poder tus datos, quién va a verificar que se cumple todo... más aún ni siquiera hay garantías de que los propios gobiernos que aprueben tales leyes, las apliquen ellos mismos.
#2976
Los chinos van a ser cada vez más problemáticos en asuntos de tecnología...

Aunque para mi, no queda tan claro, que el espionaje de los chinos, sea meramente particular, como algo impuesto por el gobierno chino. Sea como fuere, va en aumento...
#2977
Es legal, porque las leyes así lo dicen, cuando el sentido común dicta lo contrario.

Las leyes debieran partir desde el sentido común... si durante la idealización de una ley, su concepto, entorno, etc... no tiene sentido común, su camino debiera quedar truncado, porque todo apunta a generar puertas chanchulleras.

Sucede lo mismo con las SICAV (en España). En principio parece algo interesante, una oportunidad para que pequeños empresarios puedan unirse y afrontar grandes proyectos. La realidad?. Que un rico, paga a otros 99 mindundis, por formar la SICAV y él como socio mayoritario hace y dispone como le dé la gana, exactamente igual que si no fuera una SICAV, pero sujeto a todos los eximentes de impuestos previstos para las SICAV. Si yo fuera juez, iban a la cárcel, porque violan el espíritu de dicha ley. en las SICAV, claramente cada asociado debe tener una parte representativa importante, ovbiamente exigir que todos tuvieran la misma cantidad invertida sería complejo, pero ir al extremo contrario, es una pruyeba clara que su único propósito es vadear las leyes, viopando el espíritu de la ley, porque es claro, que lo que se pretende con ello es dar oportunidad a los pequeños para asociarse y competir, uno 'grande' no tiene ninguna necesidad de ese tipo de sociedad, viola el espíritu de la ley, incluso aunque la ley no recoja explicítamente un texto que así lo diga.

Sucede en prácticamente todo el mundo con la globalización de las empresas multinacionales. Ganan dinero en todos los países, pero pagan impuestos sólo en un sólo país, en el que tienen "radicado su negocio", en los demás sus declaraciones de Hacienda incluso les sale a devolver, pero la cantidad de dinero que ingresan de cada país es millonaria... las leyes... no hay prisa por cambiarlas, incluso la Unión europea conscientes del problema, tampoco parecen tener prisa.... obvio, si ellos mismos sacarán negocio directa o indirectamente. Es como poner de jefe de policía al ladrón mayor de la ciudad ¿a quién va a detener?, a lo sumo al que le haga la competencia.

Las leyes deberan dictar claramente que si una persona quiere tributar en las Bahamas, por ejemplo, no debe bastar con que tenga abierta una cuenta bancaria allí y una empresa allí, también debiera vivir allí al menos 6 meses y 1 día. Así la reina de Inglaterra, se debería trasladar allí. Pero la ley no debiera quedar ahí, debería ir más allá. Si tienes tu empresa fijada en las Bahamas, vale que tributes tus ganancias en las Bahamas, pero si tienes transacciones en Francia por valor de 100 millones, justo es que tributes en Francia por valor de 100 millones... y con lo que te reste, luego tributa en las Bahamas. Así al tener que tributar en dos países (prácticamente) por el mismo concepto, no tendrían sentido los 'paraísos fiscales' ni habría tal desfalco a las arcas de los países, por evasión de impuestos.
#2978
Cuando alguien sostenía que hombres y dinosaurios convivieron, aparte de insultos, desprecios, risas, etc... la comunidad científica (la ciencia oficial), descartaba de plano todas las teorías, sin la más mínima duda ni prueba en contra.

Al tiempo acabará poniéndose cada pieza dle puzzle de la Historia en su sitio y quedará de manifiesto las falsedades mantenidas durante décadas.

Cuando alguien plantea la teoría de la convivencia de hombres y dinosaurios desde la perspectiva (para mi obvia), de que hubo otras civilaciones desaparecidas en cataclismos, probablemente sepultadas (incluso con un vuelco de la corteza terrestre después de fragmentarse por cataclismos) la respuesta de la comunidad científica es la misma, insultos desprecios y risas.

Así que no queda otra que esperar y dar tiempo al tiempo a que ellos mismos encuentren la piezas y sean ellos mismos quienes tengan de quebrar el mal montaje del puzzle para reconstruirlo conforme a la verdad... (alo mejor lo único que quieren es ser ellos los que descubran lo que haya importante por descubrir y no cualquier 'mindundi' que lance teorías 'disparatadas'.
#2979
Desconozco que exista una función en ningún lenguaje para hacer eso.

Pueden diseñarse miles y miles de funciones... inútiles, no tiene sentido meter todas las ocurrencias en un lenguaje para que alguien las use 1 vez cada 5 años.

Precisamente por eso existe la programación, para implementar con las funcionalidad básica de un lenguaje aquello que de forma nativa no ofrece pero se necesita.

Aunque el asunto es que es son matemáticas de 10 años o así... y casi mejor que decirte otra cosa es decirte que regreses a parvulitos a estudiar aquella lección que se ve que te saltaste  :silbar: :silbar: :silbar:


// Se supone que el contenido del array serán valores comprendidos entre 0 y 9)
entero = funcion ConvertirArrayDeBytesAEntero(array de bytes valores() )
   entero valor, k

   bucle para k desde 0 hasta valores.count  
       valor += ((10 elevado a k) * valores(k))
   fin bucle
   devolver valor
fin funcion

Date cuenta, que si operamos con números (operaciones matemáticas) es preferible que el array de entrada sean también números. Si, sí o sí en origen tienes un array de cadenas, o lo conviertes previamente a un array de bytes, o haces la conversión en el propio bucle elemento a elemento, antes de realizar el cálculo.

Si el array es demasiado largo (en realidad suficientemente corto para la capacidad de un array), habrá un error de desbordamiento del entero, razón principal por la que nadie implementará tal función en un lenguaje... no pararía de generarse errores contínuamente día tras día.
Nada entorpece más (el futuro de) un lenguaje que funciones no acotadas, donde los principantes inundan las redes siempre con las mismas preguntas por no entender que están haciendo al usarlo inapropiadamente.

Si los valores son bytes (no cadenas, esto es un byte 0 tiene un valor numérico = 0, en cambio un string "0" es un byte de valor 48), pueden usarse funciones del lenguaje para copiar x bytes de un array a una variable, sin necesidad de ninguna conversión explícita. Se accede al puntero de memoria preciso, y desde ahí se copian al destino los bytes necesarios.


p.d.:
Por último señalar que si la función va a ser invocada constantemente, es más eficiente generar un array con las potencias de 10, al inicio del programa (un array estático), que recalcularlo en cada llamada a la función.

array estatico de enteros Potencias10(de 0 a 9) //con 10 alcanza hasta un valor de:  9.999.999.999

funcion InicializarPrograma
    entero k

    bucle para k desde 0 hasta 9
        potencias10(k) = 10 elevado a la k
    fin bucle

    // o un código alternativo al bucle previo:
    potencias10(0)= 1
    bucle para k desde 1 hasta 9
        potencias10(k) = (potencias10(k-1) * 10)
    fin bucle
fin funcion

//y en la línea de la función anterior:
valor +=  (10 elevado a k) * valores(k)
// la remplazas por:
valor +=  (potencias10(k) * valores(k))

#2980
jajaja... odio tWitter, y no por nada complicado, sólo por la memez estúpida del límite de caracteres. Es como decir quéjate todo lo que quieras, pero pronuncia solo 4 letras. o lo mismo que decir: "deja tu currículum, antes de salir... ...en la papelera."

Odié los SMS de los teléfonos móviles, precisamente por su limitación, y que un 'servicio' se fundamente en esa misma limitación me resulta a partes iguales increíble y penoso.

...qué mínimo que el límite fuera 1 PU70 kilobyte... que además seguramente pueda ser comprimido a la mitad o menos a la hora de enviarlo.