Нахождение индекса массива, где встречается минимальное значение - PullRequest
2 голосов
/ 12 ноября 2010

Это заставляет мою голову кружиться. Просто когда я думаю, что понял, я понимаю, что что-то не так. Я должен использовать рекурсию для этого задания. Есть намеки?

/**
 * Uses recursion to find index of the shortest string.
 * Null strings are treated as infinitely long.
 * Implementation notes:
 * The base case if lo == hi.
 * Use safeStringLength(paths[xxx]) to determine the string length.
 * Invoke recursion to test the remaining paths (lo +1)
 */
static int findShortestString(String[] paths, int lo, int hi) {
    int min=lo;
    if (lo==hi)
        return min;
    if (safeStringLength(paths[lo]) < safeStringLength(paths[lo+1])){
        min=lo;
        return Math.min(min, findShortestString(paths, lo+1, hi));
    }
    else{
        min=lo+1;
        return Math.min(min, findShortestString(paths, lo+1, hi));
    }
}

Ответы [ 7 ]

4 голосов
/ 12 ноября 2010

Я думаю, что получил кое-что здесь:

static int findShortestString(String[] paths, int lo, int hi) 
{
    if (lo==hi)
        return lo;

    int ShortestIndexSoFar = findShortestString(paths, lo+1, hi);
    if(safeStringLength(paths[ShortestIndexSoFar]) < safeStringLength(paths[lo]))
        return ShortestIndexSoFar;
    else
        return lo;
}  

static int safeStringLength(String str)
{
    if(str == null)
        return Integer.MAX_VALUE;
    return str.length();
}

Объясняя, почему это работает:
Вот пример:

[0] ab
[1] abcd
[2] a
[3] abc
[4] ab

Очевидно, индекс 2 является самым коротким.
Подумай снизу вверх.Прочитайте следующее, начиная снизу вверх.
Я звучу так, будто каждая функция говорит с функцией над ней в цепочке.
И каждая строка опережает переданные параметры функции.

"[0] ab   (paths, 0, 4): return 2, coz he's shorter than me or anyone before us"
"[1] abcd (paths, 1, 4): return 2, coz he's shorter than me or anyone before us"
"[2] a    (paths, 2, 4): return 2, I'm shorter than anyone before me"
"[3] abc  (paths, 3, 4): return 4, coz he's shorter than me or anyone before us"
"[4] ab   (paths, 4, 4): return 4, I'm the shortest; I don't know any better"

Итак, в коде вы видите, что именно это происходит.
Когда мы определяем ShortestIndexSoFar, именно здесь каждая функция узнает самый короткий из всех путей за ней.
И сразу после негогде функция сама проверяет, имеет ли ее индекс более короткий путь, чем самый короткий из всех приведенных ниже.
Продолжайте перетекать самый короткий вверх, и последний парень вернет самый короткий индекс.

Что имеет смысл?

1 голос
/ 12 ноября 2010

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

Подпись метода findShortestString предполагает, что вы должны использовать бинарный поиск.Зачем мне это говорить?Почему это было бы хорошей идеей сделать это?Все другие решения страдают от практической проблемы в Java ... что бы это было?

Людям, отличным от OP ... ПОЖАЛУЙСТА, НЕ ДАВАЙТЕ ОТВЕТОВ ... напримерисправляя свои ответы!

0 голосов
/ 12 ноября 2010
static int findShortestString(String[] paths, int lo, int hi)
{  
  if (lo==hi)  
    return lo;  
  int ShortestIndexDown = findShortestString(paths, lo, (hi + lo)/2);
  int ShortestIndexUp = findShortestString(paths, (lo+hi)/2+1, hi);
  return SafeStringLength(paths[ShortestIndexDown]) < SafeStringLength(paths[ShortestIndexUp])?ShortestIndexDown:ShortestIndexUp;
}

static int safeStringLength(String str)
{
  if(str == null)
    return Integer.MAX_VALUE;
  return str.length();
}
0 голосов
/ 12 ноября 2010

Вычисление min по результату выполнения findShortestString не имеет смысла.Лучший способ начать такую ​​проблему - рассмотреть только один рекурсивный шаг, вы можете сделать это, учитывая, что происходит с массивом, состоящим только из двух строк, для сравнения.

Что вы хотите сделать, это проверитьдлина первой строки в зависимости от длины второй.Реальный трюк, однако, заключается в том, что вы хотите проверить длину секунды, вызывая функцию рекурсивно.Это достаточно просто, но требует определения конца вашей рекурсии.Вы сделали это успешно, это когда lo == hi.То есть, когда lo == hi самая короткая из известных строк, это lo (это единственная известная строка!).

Хорошо, так что вернемся к сравнению только двух строк.Учитывая, что вы знаете, что хотите сравнить длину двух строк, хранящихся в paths, вы можете сделать что-то вроде этого (без рекурсии):

if(safeStringLength(paths[0]) < safeStringLength(paths[1])){
    return 0; // paths[0] is shorter
}else{
    return 1; // paths[1] is shorter
}

Но вы хотите повторить - и вшаг recurse вам нужно как-то сгенерировать это 1 из paths[1].Мы уже выяснили, как это сделать, когда lo == hi, мы возвращаем lo.Таким образом, шаг рекурсии «сравнить текущую самую низкую известную длину строки с длиной строки самого известного индекса» - подождите, у нас есть функция для этого!это findShortestString.Таким образом, мы можем изменить то, что написано выше, чтобы быть немного более кратким, и добавить в базовый вариант, чтобы получить:

static int findShortestString(String[] paths, int lo, int hi) {
    // base case, no comparisons, the only known string is the shortest one
    if(lo == hi){
        return lo;
    }

    int bestIndex = findShortestString(paths, lo+1, hi);
    return safeStringLength(paths[lo]) < safeStringLength(paths[bestIndex]) ? 
        lo : bestIndex;
}
0 голосов
/ 12 ноября 2010

Простое решение:

/**
     * Uses recursion to find index of the shortest string.
     * Null strings are treated as infinitely long.
     * Implementation notes:
     * The base case if lo == hi.
     * Use safeStringLength(paths[xxx]) to determine the string length.
     * Invoke recursion to test the remaining paths (lo +1)
     */
static int findShortestString(String[] paths, int lo, int hi) {
    if (lo==hi)
        return lo;
    if (paths[lo] == null)
       return findShortestString(paths, lo+1, hi);
    int bestIndex = findShortestString(paths, lo+1, hi);
       if (safeStringLength[lo] < safeStringLength[bestIndex])
           return lo;
    return bestIndex;
}
0 голосов
/ 12 ноября 2010

одно решение будет таким

public static final int findShortestString(final String[] arr, final int index, final int minIndex) {

    if(index >= arr.length - 1 ) {
        return minIndex;
    }

    if(-1 == safeStringLength(arr[index])) { 
        return index;
    }


    int currentMinIncex = minIndex;

    if(safeStringLength(arr[minIndex]) > safeStringLength(arr[index+1])){
        currentMinIncex = index + 1;
    }


    return findShortestString(arr, index + 1, currentMinIncex);

}



public static final int safeStringLength(final String string) {

    if( null == string) return -1;

    return string.length();

}
0 голосов
/ 12 ноября 2010

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

<code>int[] intArray = {10, 17, 8, 99, 1}; // length of each element of string array
Arrays.sort(intArray);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...