Menu
Coddy logo textTech

Funkcje rekurencyjne

Część sekcji Logika i przepływ sterowania ścieżki R w Coddy. Lekcja 50 z 64.

Funkcja rekurencyjna wywołuje samą siebie dla mniejszej wersji problemu. Potrzebuje przypadku bazowego, który zwraca wynik bez wywoływania samej siebie, w przeciwnym razie nigdy by się nie zatrzymała:

fact <- function(n) {
  if (n <= 1) return(1)
  n * fact(n - 1)
}
print(fact(5))

Wynik:

[1] 120

Każde wywołanie czeka na zakończenie mniejszego wywołania: fact(3) oblicza 3 * fact(2), które oblicza 2 * fact(1), które zwraca 1. Każdy krok musi prowadzić do przypadku bazowego:

count_down <- function(n) {
  if (n == 0) {
    cat("go\n")
    return(invisible(NULL))
  }
  cat(n, "")
  count_down(n - 1)
}
count_down(3)

Wynik:

3 2 1 go

Rekurencja pasuje do danych zawierających mniejsze kopie samych siebie, takich jak lista przechowująca listy. Ta funkcja dodaje wszystkie liczby, niezależnie od głębokości ich zagnieżdżenia:

deep_sum <- function(x) {
  if (is.numeric(x)) return(sum(x))
  total <- 0
  for (item in x) total <- total + deep_sum(item)
  total
}
print(deep_sum(list(1, list(2, 3), list(list(4)), 5)))

Wynik:

[1] 15

Wywołanie rekurencyjne może również podzielić problem na pół. Wyszukiwanie binarne sprawdza środkowy element posortowanego wektora i kontynuuje w tej połowie, w której może znajdować się szukana wartość:

find <- function(v, target, lo = 1, hi = length(v)) {
  if (lo > hi) return(NA)
  mid <- (lo + hi) %/% 2
  if (v[mid] == target) return(mid)
  if (v[mid] < target) find(v, target, mid + 1, hi) else find(v, target, lo, mid - 1)
}
print(find(c(2, 5, 8, 12, 19), 12))
print(find(c(2, 5, 8, 12, 19), 7))

Wynik:

[1] 4
[1] NA
challenge icon

Wyzwanie

Łatwy

Uzupełnij rekurencyjnie count_digits(n). Liczba mniejsza niż 10 ma 1 cyfrę; każda większa liczba ma o jedną cyfrę więcej niż n %/% 10. Nie zamieniaj liczby na tekst.

Dostarczony kod odczytuje liczbę całkowitą n (0 lub większą) i wypisuje zwróconą wartość.

Spróbuj swoich sił

count_digits <- function(n) {
  # Wpisz tutaj swój kod
  0
}

# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input <- suppressWarnings(readLines(file("stdin")))
cat(count_digits(as.numeric(input[1])), sep = "\n")
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Logika i przepływ sterowania

Poćwicz samodzielnie: Kompilator R online