简体   繁体   English

如何递归地反转字符串数组?

[英]How to reverse an array of strings recursively?

supposed to reverse an array of strings recursively. 应该递归地反转字符串数组。

having trouble implementing this. 难以实施。 if i was using a for loop i would just start it at the end of the array and print out the array starting with the last element and ending with the first. 如果我使用的是for循环,则只需在数组的末尾将其启动,并从最后一个元素开始到第一个元素为止打印出该数组。

I'm not too sure how to do it recursively. 我不太确定如何递归执行。 i was thinking about using a swap but that idea sort of fizzled when i couldnt figure out how to change the elements that i was swapping. 我当时正在考虑使用交换,但是当我想不出如何更改交换元素时,这个想法就失败了。

any ideas or a push in the right direction would be appreciated. 任何想法或朝正确方向的推动将不胜感激。


this is what icame up with so far. 到目前为止,这就是我的目的。 i know its wrong, i get an error out of bounds exception which im not sure how to fix. 我知道它的错误,我收到了超出范围的异常错误,我不确定该如何解决。 I think im not swapping the first and last correctly. 我认为即时通讯无法正确交换第一个和最后一个。 but am i getting the right idea? 但是我有正确的主意吗?

this is what i came up with. 这就是我想出的。 a is an array. a是一个数组。 its inside a class. 它在一个类中。

// reverse an array 

public void rev() 
{
    rev(0,a.length-1);
} 

private void rev(int first, int last)
{
if(last == 0)
{
//do nothing
}

else
{
while(first != last)
{
int temp = first;
first = last;
last = temp;


System.out.print(" " + a[first]);
rev((first + 1), (last - 1));
}

}
}

made some changes and it reverses the last 3 elements but the it repeats the second element. 进行了一些更改,它反转了最后3个元素,但它重复了第二个元素。 i have no if statement that controls when it runs so shouldnt it run until left = right? 我没有控制运行时间的if语句,因此它不应该运行直到left = right吗?

this is what i changed it to 这就是我将其更改为

// reverse an array 
public void rev() 
{
    rev(0,a.length-1);
} 

private void rev(int first, int last)
{
    if(last == 0)
    {
    //do nothing
    }

    else
    {


    String temp = a[first];
    a[first] = a[last];
    a[last] = temp;

    System.out.print(" " + a[first]);
    rev(first+ 1, last-1);

    }
}

The trick with recursion is to try and think of the problem in terms of a base case and then a way to reduce everything to that base case. 递归的技巧是尝试根据基本情况思考问题,然后将所有内容简化为基本情况。

So, if you're trying to reverse a list then you can think of it like this: 因此,如果您要反转列表,则可以这样考虑:

  1. The reverse of a list of size 1 is that list. 大小为1的列表的反面就是该列表。
  2. For a list of size > 1 then the first element in the output list will be the last element of the input list. 对于size > 1的列表,输出列表中的第一个元素将是输入列表的最后一个元素。
  3. The rest of the output list will be the reverse of the input list, minus the last element. 输出列表的其余部分将与输入列表相反,减去最后一个元素。

You now have your recursive definition. 现在,您有了递归定义。

Hope that helps. 希望能有所帮助。

the while loop is too much, since you are using recursion anyway, try it like this while循环太多了,因为无论如何您都在使用递归,因此请尝试这样

private void rev(int first, int last)
{
   if(first < last)
   {
      var temp = a[first];
      a[first] = a[last];
      a[last]  = temp;
      rev(first + 1, last - 1);
   }
}

I always like having a simple public method that calls the private recursive one. 我一直喜欢有一个简单的公共方法来调用私有递归方法。 That way from other places in your code you just give it the array, and don't have to worry about the other arguments. 通过这种方式,您可以从代码的其他位置开始为它提供数组,而不必担心其他参数。 Also, this catches empty arrays, but you would still need to check for null at some point near the start. 同样,这会捕获空数组,但是您仍然需要在开始附近的某个点检查null。 Maybe throw an exception in the public method if the array is null? 如果数组为null,也许在公共方法中引发异常?

public String[] reverseArray(String[] theArray) {
    this.reverseArrayWorker(theArray, 0, theArray.length -1);
}

private String[] reverseArrayWorker(String[] theArray, int left, int right) {
    // Check your base cases first
    if (theArray.length <= 1) {
        // Array is one element or empty
        return theArray;
    } else if (left - right <= 0) {
        // If there are an odd # of items in the list you hit the center
        // If there are an even number your indexes past each other
        return theArray;
    }
    // Make the recursive call
    this.reverseArrayWorker(theArray, left + 1, right - 1);
    // Switch the two elements at this level
    String temp = theArray[left];
    theArray[left] = theArray[right];
    theArray[right] = temp;
    // Return the array up a level
    return theArray;
}

This will work too. 这也将起作用。 Kinda Lisp-like solution. 类似于Kinda Lisp的解决方案。

public static List<String> append(String x, List<String> xs) {
    xs.add(x);
    return xs;
}

public static List<String> reverse(List<String> xs) {
    return xs.isEmpty()
            ? xs
            : append(xs.get(0), reverse(xs.subList(1, xs.size())));
}

I/O: 输入/输出:

List          ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Reversed list ==> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
public int[] reverse(int[] returnMe, int[] original, int curPos){
    if (original.length == 1){
        return original;
    }else{
        if (curPos < original.length){
            returnMe[curPos] = original[original.length - 1 - curPos];
            reverse(returnMe, original, curPos + 1);
        }else{
            return returnMe;
        }
    }
}    

Here is an example (but without A String since it is homework) but hopefully it will give you the idea. 这是一个示例(但由于没有作业,所以没有A String),但希望它将为您带来灵感。

public static List<Character> reverse(List<Character> chars) {
    return chars.isEmpty() ? chars : 
     addToList(chars.get(0), reverse(chars.subList(1, chars.length()));
}

public static T List<T> addToList(T t, List<T> ts) {
    List<T> ret = new ArrayList<T>();
    ret.addAll(ts);
    ret.add(t);
    return ret;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM