Ortak harfleri ekrana basan program

#1
  1. For döngüsü ile aşağıdaki gibi iki karakter dizisi
    olduğunu varsayarak her iki karakter dizisinde blulunan
    harfleri ekrana basan programı yazınız
    ilk=“sdlkfjsldkfjwernwömfndsömcnösmdnfsldkfjsld”
    iki=“dskcjsdlkcjsdslrejfdslvkjdxlk”
#2
metin1 = input("Birinci metninizi giriniz :")
metin2 = input("İkinci metninizi giriniz :")
liste = []
anahtar = 0
for harf in metin1:
    if harf == " ":
        break
    if harf in metin2:
        if harf in liste:
            break
        liste.append(harf)
print(liste)

amatörce birşey yaptım ama işini görür :blush::smile:

#3
ilk =  "sdlkfjsldkfjwernwömfndsömcnösmdnfsldkfjsld"
iki =  "dskcjsdlkcjsdslrejfdslvkjdxlk"

i = [q for q in ilk]
l = [q_1 for q_1 in iki]

c = input("İlk harfi giriniz")
p = input("İkinci harfi giriniz")

if c and p in i and l:
    print("İki harfte bulunuyor.")
else:
    print("Biri ya da hiçbiri bulunmuyor ") # Ayriyetten bir daha statement yapmak istemedim siz ekliyebilirsiniz.

List Comprehensions

dediğimiz yapıyı kullanarak yapabiliriz.

#4

Buna gerek yok. Performans düşürür. i = list(ilk) ile aynı şey zaten. Listelere de gerek yok, çünkü karakter dizileri de iterator’dur zaten.

@vahvah , konu başlığını daha anlamlı bir başlıkla değiştirebilir misiniz?

#5

direk karakter dizisi içerisindende yapılabilir liste kullandığı için kullandım yoksa direk

girdi istenip if girdi in … şeklinde sağlanabilir.

>>> timeit.timeit("[q for q in a]",globals=globals())
0.5007499419989472
>>> timeit.timeit("list(a)",globals=globals())
0.2679310639996402

arada dehşet fark var aynı şekilde copy methodunda v.s de geçerli bir [:] şeklinde kopyalamak bir de method kullanıp kopyalamak var o zaman da methodlar her zaman daha seri çalışıyor

2 Likes
#6

Gormez, ornek metinde bile calismiyor.

Evet:

print([h for h in ilk if h in iki])
#7

Tek satıra düşürmek performansı yine arttıracaktır fakat yine de list methodu daha seri çalışıyor list kullanacaksak da 0 25 0.25 yine 0.50 olacak bu şekilde de aslında aynı mantığa geliyor performans acısından

#8

Tek satır olmanın performansla alakası yok. Yorumlayıcı fazladan yeni satır karakteri okuyor o kadar.

#9

Deneyelim istiyorsanız var mi yok mu yazın bir tek bir de aralarına boşluk ekliyerek

#10

@ismailarilik burada konuyu çok güzel açıklamış.

#11

Kısa olan kod mantıklı olan koddur kısacası bir işi kısa halletmek yani az satırla çalıştırmak daha hizli olacaktır

#12

teşekkür ederim mmmmmmm

#13

Kodun uzunluğunun performansıyla zerre kadar alakası yok. Kısa bir kod onunla aynı işi yapan uzun koda göre hızlı da olabilir, yavaş da. Bu tamamen kod ile alakalı bir şey.

#14

Çok basit bir örnek vereyim. İçinde 1 milyon eleman bulunan ve sıralı olan bir dizide, düz for döngüsü ile arama yapmaya kalkarsan geçen zaman 1 milyon komut süresi olur. Kod çok kısa

def search(arr, x): 
	for i in range(len(arr)): 
		if arr[i] == x: 
			return i 
	return -1

Ama aynı kodu binary search ile yeniden yazarsan kodun uzar ama süre logaritmik olarak azalır.

def binarySearch (arr, l, r, x): 
	if r >= l: 
		mid = l + (r - l)/2
		if arr[mid] == x: 
			return mid 
		elif arr[mid] > x: 
			return binarySearch(arr, l, mid-1, x) 
		else: 
			return binarySearch(arr, mid + 1, r, x) 
	else: 
		return -1

Çok basit bir örnek, daha nice veri yapıları var bunun gibi. Önemli olan, yukarıda da denildiği gibi, algoritmadır. Satır sayısı önemli değildir.

3 Likes
#15

Neden logaritmik olarak azalıyor? ( okulda Henüz logaritmaya geçmedik.)

#16

@coderistan

mid değişkeninin veri tipini int yapmak gerekiyor. Bir de l ve r parametrelerine tam olarak ne yazılması gerekiyor?

Mesela paylaştığınız kodlarla bir kaç deneme yapayım dedim, çok bir fark görmedim.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import timeit


def f1(arr, x): 
    for i in range(len(arr)): 
        if arr[i] == x: 
            return i
    return -1

	        
def f2(arr, l, r, x): 
    if r >= l: 
        mid = int(l + (r - l)/2)
        if arr[mid] == x: 
            return mid 
        elif arr[mid] > x: 
            return f2(arr, l, mid-1, x) 
        else: 
            return f2(arr, mid + 1, r, x)
        return -1
		

arr = [i for i in range(10 ** 6)]

print(timeit.timeit(f"{f1(arr, 57821)}"))
# Sonuç: 0.010027280000031169
print(timeit.timeit(f"{f2(arr, 0, 10 ** 6, 57821)}"))
# Sonuç: 0.010062176000246836
#17

Çünkü her seferinde dizinin bir yarısını eliyor. Sadece bir kısmına bakıyor. Sürekli olarak da 2’ye bölüyor. Logaritmayı 2 tabanında alıyoruz tabi bu arada.

log2 1000000 = 19.93

1 Like
#18

Öncelikle bahsettiğim durum en kötü durum için, yani aradığımız elemanın en sonda olma ihtimali. Bu yüzden aranan değere, dizinin sonunda bulunan değeri yazıyorum. l ve r değerlerine, arama yapılan dizinin baş ve son indis değerleri verilecek. Kodu şu şekilde düzelttiğim zaman, ben de gözle görülür bir fark oluşuyor.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import timeit


kod1 = """
def f1(arr, x): 
    for i in range(len(arr)): 
        if arr[i] == x: 
            return i
    return -1

arr = [i for i in range(10 ** 6)]
f1(arr, 10**6-1)
"""

kod2 = """	        
def f2(arr, l, r, x): 
    if r >= l: 
        mid = int(l + (r - l)/2)
        if arr[mid] == x: 
            return mid 
        elif arr[mid] > x: 
            return f2(arr, l, mid-1, x) 
        else: 
            return f2(arr, mid + 1, r, x)
        return -1
        
arr = [i for i in range(10 ** 6)]
f2(arr, 0,10**6,10**6-1)
"""


print(timeit.timeit(stmt = kod1,number=2))
# 0.7054800316010079
print(timeit.timeit(stmt = kod2,number=2))
# 0.29855470813155927

Ek olarak, zamandan bağımsız bir şekilde iki fonksiyonun kaç kez karşılaştırma işlemi yaptığını da şöyle basit bir şekilde görebiliriz

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def f1(arr, x):
    global comparison
    
    for i in range(len(arr)):
        comparison += 1
        if arr[i] == x: 
            return i
    return -1

	        
def f2(arr, l, r, x):
    global comparison
    comparison += 1
    
    if r >= l: 
        mid = int(l + (r - l)/2)
        if arr[mid] == x: 
            return mid 
        elif arr[mid] > x: 
            return f2(arr, l, mid-1, x) 
        else: 
            return f2(arr, mid + 1, r, x)
        return -1
		

arr = [i for i in range(10 ** 6)]
comparison = 0

f1(arr,10**6-1)
print("Comparison 1: {}".format(comparison))
# sonuç: 1000000

comparison = 0
f2(arr,0,10**6,10**6-1)
print("Comparison 2: {}".format(comparison))
# sonuç: 19
1 Like
#19

Aslında mantık olarak 2. fonksiyon belirlenen rakamı bulmaya çalışırken daha az işlem gerçekleştirir.

def f1(n: int, k: int):
    for i in range(n):
        if i == k:
            return 0
       

def f2(_min: int, _max: int, k: int):
    mid = (_min + _max) / 2
    if k == mid:
        return 0
    elif k > mid:
        return f2(_min=mid + 1, _max=_max, k=k)
    elif k < mid:
        return f2(_min=_min, _max=mid - 1, k=k)
1 Like
#20

Aynen öyle. Öncelikle dizinin ortasına bakar ve aranan değer burada değilse, aranan değerin küçük veya büyük olma durumuna göre sağ veya sol kısımdan birine bakar. Böylece arama işlemi dizinin yarısında devam ediyor. Her recursive çalıştığında dizinin bir yarısını eledigi için daha az işlem yapmış oluyor.

1 Like