# ==============================================================================
# DEFINISI FUNGSI LATIHAN 11
# ==============================================================================
# 11A. Sequential Search dengan Boolean
seq_boolean <- function(x, target) {
if (any(is.na(x))) stop("Data mengandung NA (Data tidak sah)")
ketemu <- FALSE
posisi <- NA
i <- 1
while (i <= length(x) && !ketemu) {
if (x[i] == target) {
ketemu <- TRUE
posisi <- i
}
i <- i + 1
}
return(posisi)
}
# 11B. Sequential Search Tanpa Boolean
seq_tanpa_boolean <- function(x, target) {
if (length(x) == 0) return(NA)
for (i in seq_along(x)) {
if (x[i] == target) return(i)
}
return(NA)
}
# 11C. Sequential Search pada Data Terurut
seq_terurut <- function(x, target) {
for (i in seq_along(x)) {
if (x[i] == target) return(i)
if (x[i] > target) return(paste("Berhenti pada indeks", i, "karena nilai", x[i], "> target", target))
}
return(NA)
}
# 11D. Sequential Search dengan Sentinel
seq_sentinel <- function(x, target) {
n <- length(x)
x_temp <- c(x, target)
i <- 1
while (x_temp[i] != target) {
i <- i + 1
}
if (i <= n) return(i) else return(NA)
}
# ==============================================================================
# EKSEKUSI LATIHAN 11
# ==============================================================================
lat_x <- c(12, 7, 19, 7, 25)
# 11A. Sequential Boolean posisi pertama 7
print(seq_boolean(lat_x, 7))
## [1] 2
# 11B. Tanpa Boolean target tidak ada dan larik kosong
print(seq_tanpa_boolean(lat_x, 8))
## [1] NA
print(seq_tanpa_boolean(numeric(), 8))
## [1] NA
# 11C. Terurut berhenti ketika nilai melebihi target
print(seq_terurut(c(5, 10, 15, 20, 25), 12))
## [1] "Berhenti pada indeks 3 karena nilai 15 > target 12"
# 11D. Sentinel dan keutuhan data asli
lat_awal <- lat_x
print(seq_sentinel(lat_x, 99))
## [1] NA
print(identical(lat_x, lat_awal))
## [1] TRUE
# 11E. Posisi pertama berbeda dengan semua posisi
print(match(7, lat_x))
## [1] 2
print(which(lat_x == 7))
## [1] 2 4
# 11F. Data tidak sah ditolak dan pesan ditangkap
print(tryCatch(
seq_boolean(c(12, NA, 19), 19),
error = function(e) conditionMessage(e)
))
## [1] "Data mengandung NA (Data tidak sah)"
# ==============================================================================
# DEFINISI FUNGSI LATIHAN 12
# ==============================================================================
# 12A & 12F. Jejak Pencarian Biner (Mengembalikan data frame batas & posisi tengah)
jejak_binary <- function(x, target) {
rendah <- 1
tinggi <- length(x)
langkah <- 1
jejak <- data.frame(Langkah = integer(), Rendah = integer(), Tengah = integer(), Tinggi = integer(), NilaiTengah = numeric())
while (rendah <= tinggi) {
tengah <- floor((rendah + tinggi) / 2)
jejak <- rbind(jejak, data.frame(Langkah = langkah, Rendah = rendah, Tengah = tengah, Tinggi = tinggi, NilaiTengah = x[tengah]))
if (x[tengah] == target) {
break
} else if (x[tengah] < target) {
rendah <- tengah + 1
} else {
tinggi <- tengah - 1
}
langkah <- langkah + 1
}
return(jejak)
}
# 12B & 12E. Binary Search dengan Boolean (+ Validasi Data Terurut)
bin_boolean <- function(x, target) {
# Validasi data terurut (Latihan 12E)
if (is.unsorted(x)) stop("Data belum terurut (Unsorted Data)")
rendah <- 1
tinggi <- length(x)
ketemu <- FALSE
posisi <- NA
while (rendah <= tinggi && !ketemu) {
tengah <- floor((rendah + tinggi) / 2)
if (x[tengah] == target) {
ketemu <- TRUE
posisi <- tengah
} else if (x[tengah] < target) {
rendah <- tengah + 1
} else {
tinggi <- tengah - 1
}
}
return(posisi)
}
# 12B & 12D. Binary Search Tanpa Boolean
bin_tanpa_boolean <- function(x, target) {
rendah <- 1
tinggi <- length(x)
while (rendah <= tinggi) {
tengah <- floor((rendah + tinggi) / 2)
if (x[tengah] == target) return(tengah)
if (x[tengah] < target) rendah <- tengah + 1 else tinggi <- tengah - 1
}
return(NA)
}
# 12C. Binary Search Varian Posisi Pertama (Kembalikan kemunculan pertama)
bin_pertama <- function(x, target) {
rendah <- 1
tinggi <- length(x)
res <- NA
while (rendah <= tinggi) {
tengah <- floor((rendah + tinggi) / 2)
if (x[tengah] == target) {
res <- tengah
tinggi <- tengah - 1 # Terus cari ke sebelah kiri
} else if (x[tengah] < target) {
rendah <- tengah + 1
} else {
tinggi <- tengah - 1
}
}
return(res)
}
# 12F. Hitung Kunjungan Sequential Search
kunjungan_sequential <- function(x, target) {
kunjungan <- 0
for (i in seq_along(x)) {
kunjungan <- kunjungan + 1
if (x[i] == target) break
}
return(kunjungan)
}
# Data Contoh untuk Latihan 12D (Tabel Produk)
produk_asli <- data.frame(
kode = c(105, 101, 103, 102, 104),
nama = c("Produk E", "Produk A", "Produk C", "Produk B", "Produk D"),
stok = c(12, 50, 25, 30, 15)
)
urutan <- order(produk_asli$kode)
produk_urut <- produk_asli[urutan, ]
# ==============================================================================
# EKSEKUSI LATIHAN 12
# ==============================================================================
lat_urut <- seq(10, 100, by = 10)
# 12A. Jejak pencarian 80
print(jejak_binary(lat_urut, 80))
## Langkah Rendah Tengah Tinggi NilaiTengah
## 1 1 1 5 10 50
## 2 2 6 8 10 80
# 12B. Kasus batas pada kedua varian binary
print(bin_boolean(lat_urut, 10))
## [1] 1
print(bin_tanpa_boolean(lat_urut, 100))
## [1] 10
print(bin_boolean(lat_urut, 105))
## [1] NA
# 12C. Duplikasi dan posisi pertama
print(bin_boolean(c(10, 20, 20, 20, 30), 20))
## [1] 3
print(bin_pertama(c(10, 20, 20, 20, 30), 20))
## [1] 2
# 12D. Kode 103 pada tabel produk
p <- bin_tanpa_boolean(produk_urut$kode, 103)
print(c(posisi_terurut = p, baris_asli = urutan[p]))
## posisi_terurut baris_asli
## 3 3
print(produk_urut[p, , drop = FALSE])
## kode nama stok
## 3 103 Produk C 25
# 12E. Validasi menolak data yang belum terurut
print(tryCatch(
bin_boolean(c(30, 10, 20), 20),
error = function(e) conditionMessage(e)
))
## [1] "Data belum terurut (Unsorted Data)"
# 12F. Bandingkan kunjungan target terakhir
print(c(
sequential = kunjungan_sequential(seq_len(1024), 1024),
binary = nrow(jejak_binary(seq_len(1024), 1024))
))
## sequential binary
## 1024 11