Bölüm 8: Yığın ve Kuyruk Uygulamaları

Bölüm 8: Yığın ve Kuyruk Uygulamaları · Çalışma Soruları
Labirent ve geri izlemeİfade gösterimleriPostfix hesaplamaInfix → postfixPrefixParantez ve geri al
Sercan KÜLCÜ

Çoktan Seçmeli · Labirent

Soru 1: Hareket Tablosu

Yön 0 kuzey olmak üzere yönler saat yönünde numaralanıyor: hareket[5] = {1, -1} (dikey, yatay). (3, 4) hücresinden yön 5 ile hangi hücreye gidilir ve bu yönün adı nedir?

C: Yeni konum [i + dikey][j + yatay] = [3 + 1][4 − 1] = (4, 3). Dikey +1 bir satır aşağı (güney), yatay −1 bir sütun sola (batı) demektir. Yön 1 kuzeydoğu, 3 güneydoğu, 7 kuzeybatıdır.

Adım Adım Çalıştırma · Labirent

Soru 2: Küçük Labirentte izbul

Çevresi 1 ile çevrili 6×6 labirentte giriş (1, 1), çıkış (4, 4). izbul hangi yolu bulur, nerede geri adım atar?

012345012345GÇ

Yığında (satır, sütun, yön) = (1, 1, 1); gezildi[1][1] = 1. Çıkış (4, 4).

012345012345GÇ

pop: (1, 1)'den yön 1 ile devam edilir.

012345012345GÇ

Yön 1 (0, 2) duvar; yön 2 (D) (1, 2) açık. Dönüşte yön 3'ten sürmek üzere (1, 1, 3) push.

012345012345GÇ

(1, 2)'den yön 0–3 duvar; yön 4 (G) (2, 2) açık → (1, 2, 5) push.

012345012345GÇ

(2, 2)'den yön 0 gezilmiş, 1 ve 2 duvar; yön 3 (GD) (3, 3) açık → (2, 2, 4) push.

012345012345GÇ

(3, 3)'ten yön 0 duvar; yön 1 (KD) (2, 4) açık → (3, 3, 2) push.

012345012345GÇ

(2, 4) çıkmaz: sekiz yönün hepsi duvar ya da gezilmiş, yon 8 olur ve iç döngü biter.

012345012345GÇ

Geri adım: pop ile (3, 3)'e dönülür ve yön 2'den denemeye devam edilir.

012345012345GÇ

Yön 2 (3, 4) duvar; yön 3 (GD) (4, 4) çıkış. Yol: yığındaki üç kayıt + (3, 3) + çıkış.

while (top > -1 && !bulundu) {
  konum = yigit_al(&top);
  satir = konum.satir; sutun = konum.sutun;
  yon = konum.yon;
  while (yon < 8 && !bulundu) {
    ys = satir + hareket[yon].dikey;
    yy = sutun + hareket[yon].yatay;
    if (ys == CIKIS_SATIR && yy == CIKIS_SUTUN)
      bulundu = TRUE;
    else if (!labirent[ys][yy] &&
             !gezildi[ys][yy]) {
      gezildi[ys][yy] = 1;
      konum = (element){satir, sutun, ++yon};
      yigit_ekle(&top, konum);
      satir = ys; sutun = yy; yon = 0;
    } else ++yon;
} }

Çoktan Seçmeli · İfade Gösterimleri

Soru 3: Infix'ten Postfix'e

a - b * c / (d + e) ifadesinin postfix (sonek) karşılığı hangisidir?

B: Tam parantezleme: (a − ((b * c) / (d + e))). * ve / eşit öncelikli ve soldan birleşir: önce b * c, sonra bölme; çıkarma en son. A, a − b'yi önce yapar; C parantezi yok sayar; D çıkarmayı bölmeden önce uygular.

Klasik Soru · İfade Gösterimleri

Soru 4: Elle Önek ve Sonek

a * (b - c) / d + e ifadesini tam parantezleyin; prefix (önek) ve postfix (sonek) karşılıklarını yazın. a = 6, b = 5, c = 2, d = 9, e = 4 için değer nedir?

Cevabı göster

Tam parantezleme: (((a * (b − c)) / d) + e)

  • İşleçler sağ kapanışa taşınır → postfix: a b c - * d / e +
  • İşleçler sol açılışa taşınır → prefix: + / * a - b c d e

Değer: 6 · (5 − 2) = 18, 18 / 9 = 2, 2 + 4 = 6. İşlenenlerin sırası üç gösterimde de aynıdır (a b c d e); yalnız işleçlerin yeri değişir.

Çoktan Seçmeli · İfade Gösterimleri

Soru 5: Postfix'ten Infix'e

a b c * + d - postfix ifadesinin tam parantezli infix karşılığı hangisidir?

D: Yığınla: a, b, c girer; * → (b * c); + → (a + (b * c)); d girer; − → ((a + (b * c)) − d). İşleç geldiğinde ilk çekilen sağ işlenendir. A, + ile *'ın sırasını karıştırır.

Adım Adım Çalıştırma · Postfix Hesaplama

Soru 6: eval("84-2*93/+")

eval("84-2*93/+") çağrısında işlenen yığını nasıl değişir ve hangi değer döner?

0123top = -1

İfade 84-2*93/+; yığın boş.

80123top = 0

'8' işlenen: '8' − '0' = 8 yığına.

804123top = 1

'4' işlenen: '4' − '0' = 4 yığına.

40123top = 0

'-' işleç: op1 = 8, op2 = 4 → 8 − 4 = 4 yığına.

402123top = 1

'2' işlenen: '2' − '0' = 2 yığına.

80123top = 0

'*' işleç: op1 = 4, op2 = 2 → 4 · 2 = 8 yığına.

809123top = 1

'9' işlenen: '9' − '0' = 9 yığına.

8091323top = 2

'3' işlenen: '3' − '0' = 3 yığına.

803123top = 1

'/' işleç: op1 = 9, op2 = 3 → 9 / 3 = 3 yığına.

110123top = 0

'+' işleç: op1 = 8, op2 = 3 → 8 + 3 = 11 yığına.

110123top = 0

'\0': döngü biter; yığında kalan tek değer 11 döner. Yığın en çok 3 değer tuttu.

float eval(const char *expr) {
  float y[MAX], op1, op2; int top = -1;
  for (int n = 0; expr[n] != '\0'; n++) {
    char c = expr[n];
    if (isdigit(c)) y[++top] = c - '0';
    else {
      op2 = y[top--];
      op1 = y[top--];
      y[++top] = islem(c, op1, op2);
    }
  }
  /* sonda tek öğe kalmalı */
  return y[top];
}

Çoktan Seçmeli · Postfix Hesaplama

Soru 7: float mı, int mi?

eval yordamının yığını float yerine int dizisi olsaydı eval("72/3*") ne döndürürdü? Dersteki float sürümü ne döndürür?

A: int sürümde 7 / 2 tam sayı bölmesidir: 3, sonra 3 · 3 = 9. float sürümde 7 / 2 = 3.5, 3.5 · 3 = 10.5 (ikisi de çalıştırılarak doğrulandı). D, 10.5'in yuvarlandığını varsayar; C'de int bölme sıfıra doğru keser, sonuç hiç kesirli olmaz.

Klasik Soru · Postfix Hesaplama

Soru 8: Çok Basamaklı Postfix

Dersteki eval yalnız tek basamaklı işlenen okur. İşlenenleri boşlukla ayrılmış, çok basamaklı olabilen postfix ifadeyi (ör. "12 3 - 4 *" → 36) hesaplayan double eval2(const char *e) yordamını yazın; eksik ya da fazla işlenende NAN döndürsün.

Cevabı göster
double eval2(const char *e) {
  double y[MAX], a, b; int top = -1;
  while (*e) {
    if (isspace(*e)) { e++; continue; }
    if (isdigit(*e)) {
      double v = 0;
      while (isdigit(*e)) v = v * 10 + (*e++ - '0');
      y[++top] = v; continue;
    }
    if (top < 1) return NAN;  /* eksik işlenen */
    b = y[top--]; a = y[top--];
    switch (*e++) {
      case '+': y[++top] = a + b; break;
      case '-': y[++top] = a - b; break;
      case '*': y[++top] = a * b; break;
      default:  y[++top] = a / b;
    }
  }
  return top == 0 ? y[0] : NAN;  /* NAN: math.h */
}

Rakamlar v = v * 10 + rakam ile tek sayıya toplanır. Denemeler: "100 25 / 7 +" → 11; "5 +" ve "2 3" → NAN.

Adım Adım Çalıştırma · Infix → Postfix

Soru 9: a-b+c*(d-e) Çevirisi

postfix("a-b+c*(d-e)", cikti) çağrısında işleç yığını nasıl değişir ve sonuç nedir?

#01234top = 0

Yığının dibinde # (isp = −1) durur; döngüyü o durdurur.

#01234top = 0

a işlenen → çıktıya.

#0-1234top = 1

- : isp(#) = −1 < icp(-) = 12 → yığına.

#0-1234top = 1

b → çıktıya.

#0+1234top = 1

+ : isp(-) = 12 ≥ icp(+) = 12 → - çıktıya (soldan birleşme); + yığına.

#0+1234top = 1

c → çıktıya.

#0+1*234top = 2

* : isp(+) = 12 < icp(*) = 13 → * üste biner.

#0+1*2(34top = 3

( : icp 20 en yüksek; hiçbir şey çıkmadan girer.

#0+1*2(34top = 3

d → çıktıya.

#0+1*2(3-4top = 4

- : isp(() = 0 < 12 → yığına; yığındaki ( en düşük önceliklidir.

#0+1*2(3-4top = 4

e → çıktıya.

#0+1*234top = 2

) : ( görülene kadar al → - çıktıya; ( atılır.

#01234top = 0

Girdi bitti: önce *, sonra + çıktıya. Sonuç ab-cde-*+.

void postfix(const char *e, char *cikti) {
  char y[MAX] = {'#'}; int top = 0, k = 0;
  for (; *e; e++) {
    if (isalnum(*e)) cikti[k++] = *e;
    else if (*e == ')') {
      while (y[top] != '(')
        cikti[k++] = y[top--];
      top--;              /* '(' at */
    } else {
      while (isp(y[top]) >= icp(*e))
        cikti[k++] = y[top--];
      y[++top] = *e;
    }
  }
  while (top > 0) cikti[k++] = y[top--];
  cikti[k] = '\0';
}

Çoktan Seçmeli · Infix → Postfix

Soru 10: Gelen İşleç Neleri Çıkarır?

a + b * c - d çevrilirken - okunduğu anda yığında (alttan üste) # + * vardır. Bu adımda yığından çıktıya hangi işleçler alınır?

C: isp(*) = 13 ≥ icp(-) = 12 → * çıkar; isp(+) = 12 ≥ 12 → + de çıkar; isp(#) = −1'de durulur, sonra - yığına girer. Eşitlikte çıkarmak soldan birleşmeyi sağlar: (a + b * c) − d. Sonuç abc*+d-.

Klasik Soru · Infix → Postfix

Soru 11: Ters Çevirerek Önek

a - b / c + d ifadesini “ters çevir, postfix'e çevir, yine ters çevir” yöntemiyle prefix'e çevirin. Ara sonuçları yazın; eşit öncelikte neden > kullanılır?

Cevabı göster
  1. Ters çevirme (parantez yok): d + c / b - a
  2. Postfix'e çevirme, eşit öncelikte yığından almadan (>): d c b / a - +
  3. Yine ters çevirme: + - a / b c d

Doğrulama: + (− a (/ b c)) d = ((a − (b / c)) + d). Ters çevrilmiş ifadede soldan birleşme sağdan birleşmeye döner; >= kullanılsaydı a − (… + d) gibi yanlış gruplanırdı.

Çoktan Seçmeli · Infix → Postfix

Soru 12: Önek Hesaplamada Sıra

prefix_eval("-/82*13") ne döndürür? Yordam ifadeyi sağdan sola tarar; işleçte ilk çekilen değer sol işlenendir.

B: Sağdan sola: 3, 1 girer; * → 1 · 3 = 3; 2, 8 girer; / → op1 = 8, op2 = 2 → 4; − → op1 = 4, op2 = 3 → 1. A (2.75), postfix'teki sırayı kullanmanın sonucudur: 2 / 8 = 0.25, 3 − 0.25 = 2.75 (ikisi de çalıştırıldı).

Klasik Soru · Diğer Uygulamalar

Soru 13: Sayaçla Parantez Denetimi

Yığın yerine tek sayaç kullanan bu sürüm hangi hatalı girdileri dengeli sayar? İki örnek verin ve düzeltmeyi açıklayın.

bool dengeli(const char *e) {
  int acik = 0;
  for (; *e; e++) {
    if (*e=='(' || *e=='[' || *e=='{')
      acik++;
    else if (*e==')' || *e==']' || *e=='}')
      acik--;
  }
  return acik == 0;
}
Cevabı göster
  • "([)]": sayaç 1, 2, 1, 0 → true. Oysa ] gelince üstte ( vardır: yanlış eşleşme.
  • ")(": sayaç −1, 0 → true. Kapanan, açılandan önce gelmiştir.
  • "(a]" de true döner: tür hiç karşılaştırılmaz.

Tek tür parantezde if (--acik < 0) return false; eklemek yeter. Birden çok türde “en son açılan” bilgisi gerekir: açanlar yığına konur, kapanan üstle eşleşmeli (dersteki dengeli). Hepsi çalıştırılarak denendi.

Çoktan Seçmeli · Diğer Uygulamalar

Soru 14: Geri Al ve Yinele

Düzenleyici iki yığın kullanıyor: her yeni işlem “geri al” yığınına girer ve “yinele” yığınını boşaltır. Boş metne sırayla A yaz, B yaz, C yaz, geri al, geri al, D yaz, yinele uygulanıyor. Metin ne olur?

A: İki geri alma C'yi ve B'yi yinele yığınına taşır (metin A). D yazmak yeni bir işlemdir: yinele yığını boşalır, metin AD olur. Son yinele'nin yapacak işi kalmamıştır. B, yinele yığınının boşaltılmadığını varsayar.

Klasik Soru · Özet

Soru 15: Yığın mı Kuyruk mu: Yol Uzunluğu

Giriş (1, 1), çıkış (4, 4) olan yandaki labirentte (koyu hücreler duvar) aynı sekiz yön ve aynı sırayla kuyruklu arama (BFS) yapılsaydı bulunan yol kaç hücre olurdu? izbul'un yolu neden daha uzundur? Yığınlı aramada yığın en çok kaç kayıt tutar?012345012345GÇ

Cevabı göster

BFS hücreleri girişe uzaklık sırasıyla açar: (1, 1)'in komşusu (2, 2) çaprazdan doğrudan açılır, sonra (3, 3), sonra çıkış. Yol 4 hücre: (1, 1) → (2, 2) → (3, 3) → (4, 4).

izbul derinlik önceliklidir: yön 2 (D) yön 3'ten (GD) önce denendiği için önce (1, 2)'ye girer ve oradan devam eder; yolu 5 hücredir ve (2, 4) çıkmazına da uğrar. Yığın en çok 4 kayıt tuttu (çıkmazdayken). İki arama da O(m·p) zaman alır; yalnız BFS en kısa yolu garanti eder (C ile doğrulandı).

012345012345GÇ

Çoktan Seçmeli · Özet

Soru 16: İşleç Yığınının Boyu

Uzunluğu n olan bir infix ifade postfix'e çevrilirken işleç yığınında aynı anda en çok kaç simge bulunabilir?

D: Her simge yığına en çok bir kez girip bir kez çıkar: zaman O(n). Ama ((((a + b) … gibi bir girdide bütün açılan parantezler aynı anda yığındadır; önceliği artan işleç dizileri de (a + b * c …) yığında birikir. Ek bellek en kötü O(n)'dir.

Son

Bölüm 8: Yığın ve Kuyruk Uygulamaları — Çalışma Soruları
Konu anlatımı: Yığın ve kuyruk uygulamaları sunumu · Ders notu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.