Está en la página 1de 24

Búsqueda secuencial iterativa

#indice: str list -> int (o None si no esta)


#indice de nombre en agenda
#ej. indice("c",agenda)->1

def indice(nombre,agenda):
assert type(agenda)==list and type(nombre)==str
for i in range(len(agenda)):
if agenda[i].nombre>nombre:
return None #no esta
if agenda[i].nombre==nombre:
return i
return None #no esta (mayor que ultimo)

assert indice("c",agenda)==1
Busqueda secuencial recursiva
#indice: str list -> int (o None si no esta)
#indice de nombre en agenda
#ej. indice("c",agenda)->1

def indice(nombre,agenda,i=0):
assert type(agenda)==list and type(nombre)==str
if i>=len(agenda):
return None #no esta (mayor que ultimo)
if agenda[i].nombre>nombre:
return None #no esta
if agenda[i].nombre==nombre:
return i
return indice(nombre,agenda,i+1)

assert indice("c",agenda)==1
Algoritmos de búsqueda
• Búsqueda secuencial (o lineal)
– iterativa (con inst for) o recursiva
– ¿n° de comparaciones? O(n) “del orden de n”
– ej: ~512 comparaciones para lista de n=1024
• Búsqueda binaria
– recursiva o iterativa (con inst while)
– ¿n° de comparaciones? O(log2n) “del orden de log2n”
– Ej: ~10 comparaciones para lista de n=1024
Algoritmo de Búsqueda binaria

• ip, iu: índices del primer y último elementos


• si ip>iu, terminar (nombre no está en agenda)
• calcular im como índice de la mitad: (ip+iu)/2
• comparar nombre en la mitad con nombre buscado
• si es >, buscar en 1ª mitad (entre índices ip e im-1)
• si es <, buscar en 2ª mitad (entre índices im+1 e iu)
• si es =, entonces devolver im
Búsqueda binaria recursiva

#indice: str list -> int


#indice de nombre en agenda
#ej. indice("c",agenda)->1

def indice(nombre,agenda,ip=0,iu=len(agenda)-1):
assert type(agenda)==list and type(nombre)==str
if ip>iu: return None
im=(ip+iu)/2 #indice de la mitad
if agenda[im].nombre > nombre:
return indice(nombre,agenda,ip,im-1)
if agenda[im].nombre < nombre:
return indice(nombre,agenda,im+1,iu)
return im

assert indice("c",agenda)==1
Búsqueda binaria iterativa
#indice: str list -> int
#indice de nombre en agenda
#ej. indice("c",agenda)->1

def indice(nombre,agenda):
assert type(agenda)==list and type(nombre)==str
ip=0; iu=len(agenda)-1
while ip<=iu:
im=(ip+iu)/2
if agenda[im].nombre>nombre:
iu=im-1
elif agenda[im].nombre<nombre:
ip=im+1
else:
return im
return None #no esta

assert indice("c",agenda)==1
Instrucción while
Sintaxis
while condición:
instrucciones

Semántica
Mientras condición se cumpla (sea True) ejecutar instrucción(es)

graficamente:

False
condición
True
instrucciones
Instrucción for
Sintaxis
for variable in lista: …

Semántica
indice=0
while indice<len(lista):
variable=lista[indice]

indice += 1 #indice=indice+1

Ejemplo
total=0 total=0
for numero in L: indice=0
total += numero while indice<len(L):
numero=L[indice]
total += numero
indice += 1
Tabla/Matriz: lista de listas (“lista de 2 dimensiones”)
ejemplo
T= [ [“gabriela”,”jose”,”rosa”,”matias”], \ #fila 0: lista de nombres
[62,48,56,49], \ #fila 1: lista de notas pregunta 1
[45,52,35,48] \ #fila 2: lista de notas pregunta 2
]

¿Construcción de una tabla?


#tabla inicialmente vacia
T=[]
#construir todas las filas
filas=n°; columnas=n°
for i in range(filas):
#agregar fila i inicialmente vacia
T.append([])
#agregar valores a fila i
for j in range(columnas):
T[i].append(…) #al final de fila i
T=[["gabriela","jose","rosa","matias"],\
[62,48,56,49],\
[45,52,35,48]]

#promedios por pregunta (por filas)


for i in range(1,len(T)):
print "prom preg",i,sum(T[i])/len(T[i])

#promedios por alumno (por columnas)


for j in range(len(T[0])):
s=0.0
for i in range(1,len(T)):
s+=T[i][j]
print "prom",T[0][j],s/(len(T)-1)

Propuesto. promedios por pregunta y alumno para


T=[ [“gabriela”,62,45], [“jose”,48,52], [“rosa”,56,35], [“matias”,49,48] ]
Strings (estructura indexada inmutable)
s=”casa”; S=”CASA” #asignación
a=s+S #concatenación
len(s) #4 largo (nº de caracteres) de s
s<S #False comparacion
s[i:j] #substring entre índices i y j-1
‘a’ in s #True
for c in s: print c #muestra los caracteres de s

def inverso(x):
s=””
for c in x: s=c+s
return s
assert inverso(“roma”)==”amor”

def inverso(x): #recursivo


if x==””: return ””
return inverso(x[1:])+x[0] #inverso(cola)+cabeza

def capicua(x): return x==inverso(x)


assert capicua(“reconocer”)
Funciones: devuelven otro string (no modifican original)
x.__add__(y) añade y al final de x s + “do” ‘casado’
x.find(y) índice 1ª aparición (-1 si no) s.find(“as”) 1
x.count(y) cuenta apariciones de y en x s.count(“a”) 2
x.isalpha() True si x es alfabético s.isalpha() True
x.isdigit() True si x es numérico s.isdigit() False
x.islower() True si x en minúsculas s.islower() True
x.isupper() True si x en mayúsculas s.isupper() False
x.upper() reemplaza por mayúsculas s.upper() ‘CASA’
x.lower() reemplaza por minúsculas “CASA”.lower() ‘casa’
x.strip() elimina espacios de izq y der “ a b “.strip() ‘a b’
x.replace(y,z) reemplaza todos los y por z s.replace(‘a’,’’) ‘cs’

def fraseCapicua(frase):
frase=frase.replace(“ “,””) #eliminar espacios
frase=frase.lower() #todo a minusculas
return capicua(frase)
assert fraseCapicua(“Anita lava la tina”)
Diccionarios de Python:
estructura indexada por llave (key)
definición
>>> D={"a":2,"c":1,"d":4} #secuencia de items llave:valor con llaves distintas
buscar
>>> D["c"] #entrega valor de llave “c”
1
agregar
>>> D["b"]=3 #agrega item “b”:3 a D
>>> D
{'a': 2, 'c': 1, 'b': 3, 'd': 4} ¡orden arbitrario!
eliminar
>>> del D["c"]
>>> D
{'a': 2, 'b': 3, 'd': 4}
cambiar
>>> D["a"]=5
>>> D
{'a': 5, 'b': 3, 'd': 4}
Agenda con diccionario de Python

#agenda: dict (nombre:fono)


agenda={"a":2,"c":1,"d":4}

#buscar: str dict -> int (o None si no esta)


#buscar nombre en agenda y devolver fono
#ej: buscar("c",agenda)->1

def buscar(nombre,agenda):
assert type(agenda)==dict and type(nombre)==str
if nombre in agenda:
return agenda[nombre]
else:
return None

assert buscar("c",agenda)==1
#agregar: str int dict -> None
#agrega registro con nombre y fono a agenda
#ej: agregar("b",3,agenda)->agenda==
#{"a":2,"b":3,"c":1,"d":4}

def agregar(nombre,fono,agenda):
assert type(agenda)==dict and type(nombre)==str
if nombre in agenda: return
agenda[nombre]=fono
#borrar: str dict -> None
#borra de agenda registro con nombre
#ej:borrar("c",agenda)->agenda=={"a“:2,"d“:4}

def borrar(nombre,agenda):
assert type(agenda)==dict and type(nombre)==str
if nombre in agenda:
del agenda[nombre]
#cambiar: str num dict -> None
#cambiar fono de nombre en agenda
#ej: cambiar("a",5,agenda)->agenda==
#{"a":5,"c":1,"d":4]

def cambiar(nombre,fono,agenda):
assert type(agenda)==dict and type(nombre)==str
if nombre in agenda:
agenda[nombre]=fono
def copia(D): #de diccionario
d={} #inicialmente vacio
for llave in D: #recorre llaves de D
d[llave]=D[llave] #agrega item llave:valor a d
return d

def test(f,nombre,fono,agenda,resultado):
ag=copia(agenda)
if f==borrar:
f(nombre,ag)
else:
f(nombre,fono,ag)
return ag==resultado

assert test(agregar,"b",3,agenda,\
{"a":2,"b":3,"c":1,"d":4})
assert test(borrar,"c",None,agenda,{"a":2,"d":4})
assert test(cambiar,"a",5,agenda,{"a":5,"c":1,"d":4})
Un Heap es un árbol binario en que el menor valor está “arriba” y los
árboles izquierdo y derecho a su vez son heaps. Ejemplo:
2
/ \
5 3
/ \ /
7 8 6

A=AB(2, AB(5,AB(7,None,None),AB(8,None,None)),\
AB(3,AB(6,None,None),None)))
#menor: AB -> any
#menor valor de un Heap
#ej: menor(A)->2
def menor(A):
assert A==None or type(A)==AB
if A==None: return None
return A.valor
assert menor(A)==2
#esHeap: AB -> bool
#True si AB A es un heap
#ej: esHeap(A)->True

def esHeap(A):
assert A==None or type(A)==AB
if A==None: return True
v=A.valor
p=(A.izq==None) or v<=A.izq.valor and esHeap(A.izq)
q=(A.der==None) or v<=A.der.valor and esHeap(A.der)
return p and q

assert esHeap(A)
#agregar: any AB -> AB
#heap con x y valores de AB A
#ej: agregar(1,AB(2,None,None))->
#AB(1,AB(2,None,None),None)

def agregar(x,A):
assert A==None or type(A)==AB
if A==None: return AB(x,None,None)
m=min(x,A.valor); M=max(x,A.valor)
if altura(A.izq) <= altura(A.der):
A1=A.izq; A2=A.der
else:
A1=A.der; A2=A.izq
return AB(m, agregar(M,A1), A2)

assert agregar(1,AB(2,None,None))==\
AB(1,AB(2,None,None),None)
#borrarMenor: AB -> AB
#borrar (eliminar) primer valor de A
#ej:borrarMenor(AB(1,AB(2,None,None),AB(3,None,None)))
#->#AB(2,None,AB(3,None,None))

def borrarMenor(A):
assert A==None or type(A)==AB
if A==None: return None
v=A.valor
if A.izq==None: return A.der
if A.der==None: return A.izq
v1=A.izq.valor; v2=A.der.valor
if v1<=v2:
return AB(v1,borrarMenor(A.izq),A.der)
else:
return AB(v2,A.izq,borrarmenor(A.der))

assert borrarMenor(AB(1,AB(2,None,None),AB(3,None,None)))\
==AB(2,None,AB(3,None,None))
L=lista(2,lista(3,lista(1,None)))
LO=lista(1,lista(2,lista(3,None)))

#heapSort: lista -> lista


#lista con valores de lista L ordenados
#ej: heapsort(L)->LO
def heapsort(L):
assert esLista(L)
A=heap(L)
return heapAlista(A)
assert heapsort(L)==LO
#heap: lista -> AB
#AB (heap) con valores de lista L
#ej: heap(L)->AB(1,AB(2,None,None),AB(3,None,None))
def heap(L,A=None):
assert esLista(L)
if L==None: return A
return heap(cola(L),agregar(cabeza(L),A))
assert heap(L)==AB(1,AB(2,None,None),AB(3,None,None))
#heapAlista: AB -> lista
#lista con elementos ordenados de A
#ej:heapAlista(AB(1,AB(2,None,None),None))->
# lista(1,lista(2,None))
def heapAlista(A,L=None):
assert A==None or type(A)==AB
if A==None: return L
return lista(A.valor, heapAlista(borrarMenor(A)) )
assert heapAlista(AB(1,AB(2,None,None),None))==\
lista(1,lista(2,None))

También podría gustarte