java:使用递归的倒置字符串三角形?

时间:2013-12-04 03:08:37

标签: java

我正在尝试编写一个接受字符串并打印的方法  倒三角形。例如,如果我有  trianglePrint("abcdefgh"),输出为

abcdefgh  
 abcfgh   
  abgh 
   ab

它有点工作......只是我收到了以下错误

 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
 -1 at Triangle.trianglePrint(Triangle.java:39) at Triangle.trianglePrint(Triangle.java:43) at
 Triangle.trianglePrint(Triangle.java:43) at
 Triangle.trianglePrint(Triangle.java:43) at
 Triangle.trianglePrint(Triangle.java:43) at
 Triangle.trianglePrint(Triangle.java:17) at
 Triangle.main(Triangle.java:6)

有关我做错的任何建议吗?建议更多  有效的编码方式也将受到赞赏。

public class Triangle
{
    public static void main(String[] args)

    {
        trianglePrint("abcdefgh");
    }
    public static void trianglePrint(String string)
    {
        int length,terms ;
        length =string.length() ;
        if (length%2==0)
            terms = (length/2);
        else
            terms = (length/2) +1 ;

        trianglePrint(string,terms,length);
    }
    public static void trianglePrint(String string,int terms,int length)
    {
         String [] Array = new String [terms]; 
         int padterm= length ;

        /*if (length%2==0)
            terms = (length/2);
        else
            terms = (length/2) +1 ;
        */


        if (terms == 1)
            if (length%2==0)
               Array[0]=pad(string.substring(0,2),padterm) ;

            else
                Array[0]=pad(string.substring(0,1),padterm) ;
        else


                    Array[terms-1]=pad((string.substring(0, terms)
                               +string.substring(length-terms)),padterm);
            //use to monitor value of term
            System.out.println(terms);
                //used to monitor actual array content
            System.out.println(Array[terms-1]);
            trianglePrint(string,(terms-1),length);



    }
    public static void printList(String[] list,int position)
    {
        if (position < list.length)
            System.out.println(list[position]);
                printList(list,position+1);
    }
//pads with appropriate spaces
    public static String pad(String string,int length)
    {
        String result ;
        if (string.length() >= length)
            result = string ;
        else
            result = pad(" "+ string+" " ,length);
        return result ;
    }


 }

5 个答案:

答案 0 :(得分:0)

您需要一个条件来停止递归。如果terms为0,则Array[terms-1]将导致异常,例如:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
     at Triangle.trianglePrint(Triangle.java:46)

因此当变量temrs变为0时,我们需要停止递归。您可以将以下代码添加到trianglePrint方法,这将使您的程序正常工作。

if(0 == terms)
    {
        return;
    }

更改

public static void trianglePrint(String string,int terms,int length)
{

public static void trianglePrint(String string,int terms,int length)
{
    if(0 == terms)
    {
       return;
    }

在控制台中输出;

4
abcdefgh
3
 abcfgh 
2
  abgh  
1
   ab  

答案 1 :(得分:0)

您正在进行递归以简单地减少术语参数。这不是对递归的好用(在为尾递归优化的函数式编程语言之外),并且使用for循环可以更好地实现。这个好的递归范例实际上是缩短字符串:

public static void trianglePrint(String string) {
    trianglePrint(string, 0);
}
public static void trianglePrint(String string, int padding) {
    for (int i = 0; i < padding; i++) {
        System.out.print(" ");
    }
    System.out.println(string);
    if (string.length > 2) {
        int midpoint = string.length()/2; //assumes string length is even
        trianglePrint(string.substring(0, midpoint - 1) + string.substring(midpoint + 1), padding + 1);
    }
}

不一定是最快的代码,但非常简单。

答案 2 :(得分:0)

我使用递归编写了新代码来解决问题。我相信它比现有解决方案更短,更高效。假设是这样的:字符串有偶数个数字(你没有解释如何处理奇数个数字)

public static void solve(String word) {
    solve(word, 0);
}

public static void solve(String word, int it) {
    // print starting spaces
    for(int i = 0; i < it; i++)
        System.out.print(" ");

    // print out string
    System.out.print(word);

    // print new line
    System.out.println();

    if(word.length() > 2) {
        int newlengthperside = (word.length() - 2)/2;
        solve( word.substring(0, newlengthperside) + word.substring(word.length() - newlengthperside), it+1);
    }
}

要了解此代码,请先查看main方法。我们有一个for循环在字符串之前打印出一定数量的空格,基于传递给方法的变量,然后我们打印出字符串,然后我们打印出一个新行。然后,我们确定字符串的长度是否尚未完成,我们采用新字符串的左侧和右侧,然后再次调用该方法。一旦字符串小于或等于2个字符,这个递归就会终止。

我们还通过使用另一个只需要单词的求解重载方法来使方法易于使用,并使用该字调用主求解方法,并且0,即最初打印的空格数。

答案 3 :(得分:0)

您的算法(据我所知)似乎简化为此

public static void trianglePrint(String in,
    int offset) {
  if (offset >= in.length()) { // Terminating condition.
     return;
  }
  StringBuilder sb = new StringBuilder(offset); // For padding.
  for (int i = 0; i < offset; i++) {
    sb.append(' ');
  }
  final String padding = sb.toString(); // This is the padding, so don't clear.
  sb.append(in); // Add the current input.
  sb.append(padding); // Add more "invisible" padding.
  System.out.println(sb.toString()); // print it.
  int left = in.length() / 2; // One half.
  String lh = in.substring(0, left - 1); // the left.
  String rh = in.substring(left + 1, in.length()); // the right.
  trianglePrint(lh + rh, offset + 1); // recurse.
}

public static void trianglePrint(String in) {
  trianglePrint(in, 0);
}

答案 4 :(得分:0)

稍微不同的方法可以通过更充分地利用填充的递归来进一步简化。 StringBuilder还可以更容易地从字符串中间删除:

public static void trianglePrint2(String s) {
    System.out.println(s);
    int mid = s.length()/2;
    if (!s.replace(" ", "").equals(""))  //if not all spaces
        trianglePrint(" " + new StringBuilder(s).delete(mid-1, mid+1) + " ");
}

或者(更有效率):

public static void trianglePrint(String s) {
    trianglePrint(s, s.length()/2);
}
public static void trianglePrint(String string, int mid) {
    System.out.println(s);
    if (string.length() > mid)
         trianglePrint(" " + new StringBuilder(s).delete(mid-1, mid+1), mid);
}

两者都可以使用奇数或偶数长度。