2012-08-02 9 views
5

Esta pregunta me fue dada durante una entrevista. La entrevista es mucho más, pero todavía estoy pensando en un problema y su HTE me molesta:línea al azar en el archivo

Tiene un lenguaje que contiene las siguientes herramientas: una función rand(), while y for bucles, if declaraciones, y un método readline() (similar a python's readline()). Dadas estas herramientas, escribe un algoritmo que devuelve una línea aleatoria en el archivo. No conoce el tamaño del archivo y solo puede recorrer el contenido del archivo una vez.

+0

¿Exigieron una distribución uniforme en la línea devuelta? Porque sería trivial hacer lo contrario. – KRyan

Respuesta

7

no sé la respuesta deseada, pero mi solución sería la siguiente:

chosen_line = "" 
lines = 0 

while (current_line = readline()): 
    if (rand(0, lines) == 0): 
     chosen_line = current_line 

    lines++ 

return chosen_line 

Editar: Una buena explicación de por qué funciona este fue publicada en this comment.

+1

Esto es lo que estaban buscando. Querían ver si sabían que el producto de '(n/(n + 1))' como 'n' va de' 1' a 'p' es' 1/(p + 1) '. (Probable por inducción) –

+7

Si no ve por qué funciona el código anterior, piénselo de esta manera: toma la primera línea con probabilidad 1. Es correcto para una línea. En la segunda línea, cambia a esa línea la mitad del tiempo, por lo que la mitad de las veces tiene la primera línea, la mitad del tiempo que la segunda, buena hasta el momento. En la tercera línea, toma la tercera línea 1/3 del tiempo. Ya sabemos la mitad del tiempo restante que tenía la primera línea (1/3) y la mitad del tiempo restante la segunda (1/3). Así que sigue siendo bueno para tres líneas. Y así. –

+1

@DavidSchwartz +1 Se agradece la explicación. – Josh

0

Un método, garantizando una distribución uniforme:

(1) leer el archivo línea por línea en una matriz (o similar, por ejemplo pitón list)

(2) Usar rand() para seleccionar una número entre 0 y el índice más grande en la matriz.

Otro, no garantiza una distribución uniforme:

leer cada línea. En cada lectura, también llame a rand(). Si supera un umbral, devuelva la línea.

+3

Downvoter: explique qué está mal con esta respuesta. – Marcin

+0

Bueno, no bajé, pero es claramente inferior a la respuesta aceptada, que obtiene una distribución uniforme sin usar una matriz. Y los arreglos no eran una de las características del lenguaje que, según OP, estaban disponibles. – jahhaj

-1

Aunque es similar a la tercera opción de Marcin, la implementación de Luc siempre devuelve la primera línea, al analizar todo el archivo.

Debería ser algo como:

chosen_line = "" 
treshold = 90 
max = 100 

while chosen_line == "": 
    current_line = readline() 
    if (rand(0, max) > treshold): 
     chosen_line = current_line 

print chosen_line 

También podría volver current_line en el caso se eligió ninguna línea y leer todo el archivo.

+2

La implementación de Luc no siempre devuelve la primera línea, y esta no proporciona una distribución uniforme. -1. – geoffspear

+1

Ahora entiendo el código de Luc. Todavía está analizando todo el archivo, pero no se describe en el problema como algo que debe evitar. – gepatino

+1

No hay ninguna pista sobre cuánto tiempo puede estar el archivo. Puede ser cinco líneas, pero también cinco millones. Para obtener cualquier tipo de aleatoriedad, tendrá que leer todo el archivo para averiguarlo. Dados los problemas de capacidad, podría limitar la lectura o más o menos ... Pero no hay nada de eso en la pregunta. – Luc

Cuestiones relacionadas