Каков рабочий процесс функции Pow (x, y)? - PullRequest
3 голосов
/ 01 ноября 2019

Я прохожу курсы "sololearn" и udemy, чтобы попытаться выучить C #. Я решаю проблемы, но не могу понять, как приведенный ниже код приводит к 32 (как 32 - правильный ответ, и я пытаюсь выяснить, почему). Может ли кто-нибудь объяснить мне этот процесс, вызывающий сам метод вызывает меня, я думаю.

static double Pow(double x, int y)
{
    if (y == 0)
    {
        return 1.0;
    }
    else
    {
        return x * Pow(x, y - 1);
    }
}

static void Main()
{
    Console.Write(Pow(2, 5));
} 

Пожалуйста, извините за мое плохое кодирование. Я пытаюсь сделать это на мобильном телефоне, что сложно, ответ был 32. Может кто-нибудь объяснить почему?

Редактировать: Аплоги вот как я работаю через это. Передайте 2 и 5 Пау, проверьте, если y == 0, что ложно, теперь оно y == 5, поэтому формула x * pow(x, y-1) будет активна. X по-прежнему 2, y сейчас 4, что означает, что он снова не проходит проверку на равенство 0, этот цикл продолжается до тех пор, пока не вернется 1.0, x остался на 2, поэтому 2 * 1.0 = 2, а не 32?

Ответы [ 5 ]

9 голосов
/ 01 ноября 2019

Первое, на что следует обратить внимание, это то, что вы НЕ реализуете функцию питания. Это сделано таким образом, чтобы продемонстрировать рекурсию.

С этим, давайте посмотрим, что происходит, когда вы вызываете Pow(2, 5):

Pow(x = 2, y = 5)
    -> return 2 * Pow(2, 4)
<- 2 * 16 = 32

  Pow(x = 2, y = 4)
      -> return 2 * Pow(2, 3)
  <- 2 * 8 = 16

    Pow(x = 2, y = 3)
        -> return 2 * Pow(2, 2)
    <- 2 * 4 = 8

      Pow(x = 2, y = 2)
          -> return 2 * Pow(2, 1)
      <- 2 * 2 = 4

        Pow(x = 2, y = 1)
            -> return 2 * Pow(2, 0)
        <- 2 * 1 = 2

          Pow(x = 2, y = 0)
              -> return 1 (because y == 0)
          <- 1

Чтобы прочитать это представление стека рекурсивных вызововпроложите путь сверху вниз, глядя на то, как меняются аргументы;затем вернитесь снизу вверх, глядя на возвращаемые значения (которые я обозначаю <-).

8 голосов
/ 01 ноября 2019

Хорошо, давайте пройдемся по всему.

Прежде всего, статическая функция - это та, которую можно вызывать без необходимости создания экземпляра объекта. Существует одна подпись, которую разделяют все объекты одного класса. Двойной тип является типом в C #, и он появляется здесь, чтобы показать, каким будет конечный тип вывода функции. Pow - это имя функции, double x, int y - параметры, описываемые их типом (не очень хорошо названные, но мы оставим это на следующий день)

Итак, x - это число, а y - это степень. из этого числа. Здесь есть условие для проверки двух результатов. Если у 0, то ответ всегда 1, простая математика. В противном случае функция выполняет арифметику с использованием рекурсии (она вызывает себя снова, пока не выполнит условие завершения). Причина, по которой мы получаем 32, состоит в том, что 2x2x2x2x2 = 32. Это 2 в степени 5.

Я предполагаю, что вы знаете, что такое main и console.write.

7 голосов
/ 01 ноября 2019

Этот метод в основном вычисляет "x, возведенный в степень y". Он делает это рекурсивно образом.

Во-первых, он определяет базовый случай : все, что возведено в степень 0, равно 1.

Затем он определяет, что делать во всех остальных случаях: x * Pow(x, y - 1). Предполагая, что y большой, что такое x * Pow(x, y - 1)? Это x * x * Pow(x, y - 2), что, в свою очередь, x * x * x * Pow(x, y - 3). Смотрите образец здесь? В конце концов, вы достигнете точки, где второй аргумент, y - N, равен 0, который, как мы установили, равен 1. В этот момент, сколько x * мы получили? Точно y.

Давайте посмотрим на это в действии для Pow(2, 5):

Pow(2, 5)
2 * Pow(2, 4)
2 * 2 * Pow(2, 3)
2 * 2 * 2 * Pow(2, 2)
2 * 2 * 2 * 2 * Pow(2, 1)
2 * 2 * 2 * 2 * 2 * Pow(2, 0)
2 * 2 * 2 * 2 * 2 * 1

Отсюда результат 32.

2 голосов
/ 01 ноября 2019

Здравствуйте, его рекурсия, и она повторяется до y=1, затем возвращается 2, затем возвращается 4, 8, 16, 32 в конце. 2^5=32

1 голос
/ 01 ноября 2019

Чтобы понять каждое действие в этом рекурсивном поведении, запишите все детали, чтобы увидеть, что на самом деле происходит. Например:

using System;
namespace Tester
{
    class test 
    {
        // What Pow actually does:
        static double logPow(double x, int y) {
            var old = x; // Hold the x
            for (var i = 0; i < y; i++){ // do it y times
                x = old * x; // Multiply with it's first self
            }
            return x;
        }
        static int counter = 0;
        static double Pow(double x, int y) {
            counter++;
            Console.Write("Recursive action[" + counter + "] Y status ["+ y +"] : ");
            if (y == 0)
            {
                Console.Write("return 1.0 = " + logPow(x, y) + " \n");
                return 1.0;
            }
            else
            {
                Console.Write("return " + x + " * Pow(" + x + ", " + y + " - 1) = " + logPow(x,y-1) + " \n");
                return x * Pow(x, y - 1);
            }
        }
        static void Main() {
            Console.Write("Last Result : " + Pow(2, 5)); 
        }
    }
}

Что дает результат:

Recursive action[1] Y status [5] : return 2 * Pow(2, 5 - 1) = 32 
Recursive action[2] Y status [4] : return 2 * Pow(2, 4 - 1) = 16 
Recursive action[3] Y status [3] : return 2 * Pow(2, 3 - 1) = 8 
Recursive action[4] Y status [2] : return 2 * Pow(2, 2 - 1) = 4 
Recursive action[5] Y status [1] : return 2 * Pow(2, 1 - 1) = 2 
Recursive action[6] Y status [0] : return 1.0 = 2 
Last Result : 32

Вы можете отладить свой код, просмотрев эти данные. Также вы можете повеселиться с ним по этой ссылке: https://onlinegdb.com/Bysbxat9H

...