Осуществить рефакторинг этот рекурсивный метод?

Попробуйте это:

string line="This is a \"sample\" " ;
replaced =line.Replace(@"\", "");
5
задан George Stocker 19 February 2009 в 01:53
поделиться

11 ответов

Ваше использование статических переменных для содержания состояния вне функции будет источником трудности.

Пример рекурсивной реализации макс. () функция в псевдокоде мог бы быть:

function Max(data, size) {
    assert(size > 0)
    if (size == 1) {
        return data[0]
    }
    maxtail = Max(data[1..size], size-1)
    if (data[0] > maxtail) {
        return data[0]
    } else {
        return maxtail
    }
}

Ключ здесь является рекурсивным вызовом Max (), куда Вы передаете все кроме первого элемента и меньше, чем размер. Общее представление является этой функцией, говорит, что "максимальное значение в этих данных является или первым элементом или максимумом значений в остальной части массива, какой бы ни больше".

Эта реализация не требует никаких статических данных вне функционального определения.

Один из признаков рекурсивных реализаций является так называемым "условием завершения", которое препятствует тому, чтобы рекурсия продолжилась навсегда (или, пока Вы не получаете переполнение стека). В вышеупомянутом случае, тесте для size == 1 условие завершения.

9
ответ дан 18 December 2019 в 07:57
поделиться

"не-домашняя-работа"?

Так или иначе. Первые вещи сначала.

static int[] n = new int[] {1,2,4,3,3,32,100};
static int SIZE = n.length;

не имейте никакого отношения к параметрам Max (), с которым они совместно используют свои имена. Переместите их в основное и потеряйте "статические" спецификаторы. Они используются только однажды при вызове первой инстанции Max () из основного (). Их объем не должен расширяться вне основного ().

Нет никакой причины всех вызовов Max () для совместного использования единственного "текущего" индекса ". текущий" должно быть локально для Max (). Но затем как был бы, последовательные повторения Max () знают что значение "текущих" использовать? (Подсказка: Max () уже передает другого Max () ниже по линии некоторые данные. Добавьте "текущий" к этим данным.)

То же самое идет для maxValue, хотя ситуация здесь немного более сложна. Мало того, что необходимо передать текущий "maxValue" по линии, но когда рекурсия заканчивается, необходимо пасовать назад ее полностью первому Max () функция, которая возвратит ее основному (). Вы, возможно, должны посмотреть на некоторые другие примеры рекурсии и провести некоторое время с этим.

Наконец, Max () самостоятельно статичен. После того как Вы избавили от необходимости относиться к внешним данным (статические переменные) однако; это действительно не имеет значения. Это просто означает, что можно позвонить Max (), не имея необходимость инстанцировать объекта.

2
ответ дан 18 December 2019 в 07:57
поделиться

"Макс." функция является неправильным типом вещи записать рекурсивную функцию для - и факт, Вы используете статические значения для "текущего", и "maxValue" делает Вашу функцию не действительно рекурсивной функцией.

Почему бы не что-то немного более подсудное рекурсивному алгоритму, как факториал?

3
ответ дан 18 December 2019 в 07:57
поделиться

Как другие заметили, нет никакой потребности в рекурсии для реализации функции Max, но это может быть поучительно для использования знакомого алгоритма для экспериментирования с новым понятием. Так, вот упрощенный код с объяснением ниже:

public class RecursiveTry
{
    public static void main(String[] args)
    {
        System.out.println(Max(new int[] {1,2,4,3,3,32,100}, 0, 0));
    }   

    public static int Max(int[] n, int current, int maxValue) 
    {
        if(current < n.Length)
        {
            if (maxValue <= n[current] || current == 0))
            {
                return Max(n, current+1, n[current]);
            }
            return Max(n, current+1, maxValue);
        }
        return maxValue;
   }
}

всего статического состояния не стало как ненужное; вместо этого все передается стеку. внутренняя логика функции Max оптимизирована, и мы рекурсивно вызываем двумя различными способами только к забаве

2
ответ дан 18 December 2019 в 07:57
поделиться

Вот версия Java для Вас.

public class Recursion {

    public static void main(String[] args) {
        int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        System.out.println("Max: " + max(0, data));
    }

    public static int max(int i, int[] arr) {
        if(i == arr.length-1) {
            return arr[i];
        }

        int memo = max(i+1, arr);
        if(arr[i] > memo) {
            return arr[i];
        }
        return memo;
    }
}

Рекуррентное соотношение - то, что максимальный элемент массива является или первым элементом или максимумом остальной части массива. Условие остановки достигнуто при достижении конца массива. Отметьте использование memoization для сокращения рекурсивных вызовов (примерно) в половине.

2
ответ дан 18 December 2019 в 07:57
поделиться

Вы по существу пишете повторяющуюся версию, но используете хвостовую рекурсию для цикличного выполнения. Кроме того, путем создания такого количества переменных статичным, Вы по существу используете глобальные переменные вместо объектов. Вот попытка чего-то ближе к типичной рекурсивной реализации. Конечно, в реальной жизни при использовании языка как Java, который не оптимизирует последние вызовы, Вы реализовали бы функцию "Max" использование цикла.

public class RecursiveTry{
  static int[] n;

  public static void main(String[] args){
        RecursiveTry t = new RecursiveTry(new int[] {1,2,4,3,3,32,100});
        System.out.println(t.Max());
  }       

  RecursiveTry(int[] arg) {
    n = arg;
  }

  public int Max() {
    return MaxHelper(0);
  }

  private int MaxHelper(int index) {
    if(index == n.length-1) {
      return n[index];
    } else {
      int maxrest = MaxHelper(index+1);
      int current = n[index];
      if(current > maxrest)
        return current;
      else
        return maxrest;
    }
  }
}
0
ответ дан 18 December 2019 в 07:57
поделиться

Создание Вашей функции, зависящей от статических переменных, не является хорошей идеей. Вот возможная реализация рекурсивной функции Max:

int Max(int[] array, int currentPos, int maxValue) {
    // Ouch!
    if (currentPos < 0) {
        raise some error
    }
    // We reached the end of the array, return latest maxValue
    if (currentPos >= array.length) {
        return maxValue;
    }
    // Is current value greater then latest maxValue ?
    int currentValue = array[currentPos];
    if (currentValue > maxValue) {
        // currentValue is a new maxValue
        return Max(array, currentPos + 1, currentValue);
    } else {
        // maxValue is still a max value
        return Max(array, currentPos + 1, maxValue);
    }
}
...

int[] array = new int[] {...};
int currentPos = 0;
int maxValue = array[currentPos] or minimum int value;  
    maxValue = Max(array, currentPos, maxValue);
4
ответ дан 18 December 2019 в 07:57
поделиться

В Схеме это может быть записано очень кратко:

(define (max l)
    (if (= (length l) 1)
        (first l)
        (local ([define maxRest (max (rest l))])
          (if (> (first l) maxRest)
              (first l)
              maxRest))))

Предоставленный, это использует связанные списки и не массивы, который является, почему я не передал его элемент размера, но я чувствую, что это дистиллирует проблему к ее сущности. Это - определение псевдокода:

define max of a list as:
    if the list has one element, return that element
    otherwise, the max of the list will be the max between the first element and the max of the rest of the list
0
ответ дан 18 December 2019 в 07:57
поделиться

Более хороший способ получить макс. значение массива рекурсивно состоял бы в том, чтобы реализовать quicksort (который является хорошим, рекурсивным алгоритмом сортировки), и затем просто возвратите первое значение.

Вот некоторый код Java для quicksort.

0
ответ дан 18 December 2019 в 07:57
поделиться

Самый маленький размер кода я мог добраться:

public class RecursiveTry {
    public static void main(String[] args) {
        int[] x = new int[] {1,2,4,3,3,32,100};
        System.out.println(Max(x, 0));
    }   

    public static int Max(int[] arr, int currPos) {
        if (arr.length == 0) return -1;
        if (currPos == arr.length) return arr[0];
        int len = Max (arr, currPos + 1);
        if (len < arr[currPos]) return arr[currPos];
        return len;
    }
}

Несколько вещей:

1/, Если массив является нулевым размером, он возвращает макс. из-1 (Вы могли бы иметь другое значение маркера, скажем,-MAX_INT или выдать исключение). Я сделал предположение для ясности кода здесь, чтобы предположить, что все значения являются нулем или больше. Иначе я наперчил бы код всеми видами ненужного материала (в отношении ответа на вопрос).

2/Большинство рекурсий является 'более чистым', по-моему, если завершающийся случай без данных, а не последние данные, следовательно я возвращаю значение, которое, как гарантируют, будет меньше чем или равно макс., когда мы закончили массив. Другие могут отличаться по своему мнению, но это не был бы первый или последний раз, что они были неправы :-).

3/рекурсивный вызов просто получает макс. из остальной части списка и сравнивает его с элементом тока, возвращая максимум двух.

4/'идеальное' решение состояло бы в том, чтобы передать измененный массив каждому рекурсивному вызову так, чтобы Вы только сравнили первый элемент с остальной частью списка, устранив необходимость currPos. Но это было бы неэффективно и купит вниз гнев ТАК.

5/Это не может обязательно быть лучшим решением. Это может быть, который серым веществом был поставлен под угрозу от слишком большого использования LISP с его CAR, CDR и теми бесконечными круглыми скобками.

0
ответ дан 18 December 2019 в 07:57
поделиться

Во-первых, давайте заботиться о проблеме статического контекста... Ваш класс определяет объект, но никогда на самом деле инстанцирует того. Так как основное статически ограничено по объему, первое, что нужно сделать, получают объект, затем выполняются, это - методы как это:

public class RecursiveTry{

    private int[] n = {1,2,4,3,3,32,100};

    public static void main(String[] args){
        RecursiveTry maxObject = new RecursiveTry();
        System.out.println(maxObject.Max(maxObject.n, 0));
    }

    public int Max(int[] n, int start) {
        if(start == n.length - 1) {
            return n[start];
        } else { 
            int maxRest = Max(n, start + 1);
            if(n[start] > maxRest) {
                return n[start];
            }
            return maxRest;
        }
    }

}

Таким образом, теперь мы сделали, чтобы RecursiveTry возразил названному maxObject, который не требует статического контекста. Я не уверен, что нахождение максимума является эффективной рекурсией использования, поскольку количество повторений в традиционном методе цикличного выполнения примерно эквивалентно, но сумма используемого стека является большей рекурсией использования. Но для этого примера, я срезал бы его много.

Одно из преимуществ рекурсии - то, что Ваше состояние не должно обычно сохраняться во время повторных тестов как она, делает в повторении. Здесь, я признал использованию переменной для содержания начальной точки, потому что это - меньше ЦП, интенсивного, что передача нового интервала [], который содержит все объекты за исключением первого.

-2
ответ дан 18 December 2019 в 07:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: