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

java:使用递归的倒字符串三角形?,java,Java,我正在尝试编写一个接受字符串并打印 倒三角形。例如,如果我有 trianglePrint(“abcdefgh”),输出为 abcdefgh abcfgh abgh ab 它有点有效…只是我得到了以下错误 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 at Triangle.trianglePrint(Triangle.java:39) at Triangle.trian

我正在尝试编写一个接受字符串并打印 倒三角形。例如,如果我有
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 ;
    }


 }
公共类三角形
{
公共静态void main(字符串[]args)
{
三角打印(“abcdefgh”);
}
公共静态无效三角形打印(字符串)
{
整数长度,术语;
length=string.length();
如果(长度%2==0)
术语=(长度/2);
其他的
术语=(长度/2)+1;
三角打印(字符串、术语、长度);
}
公共静态void trianglePrint(字符串、整数项、整数长度)
{
字符串[]数组=新字符串[术语];
int padterm=长度;
/*如果(长度%2==0)
术语=(长度/2);
其他的
术语=(长度/2)+1;
*/
如果(术语==1)
如果(长度%2==0)
数组[0]=pad(string.substring(0,2),padterm);
其他的
数组[0]=pad(string.substring(0,1),padterm);
其他的
数组[terms-1]=pad((string.substring(0,terms))
+子字符串(长度项)),padterm);
//用于监视术语的值
系统输出打印项次(条款);
//用于监视实际数组内容
System.out.println(数组[terms-1]);
三角形打印(字符串,(术语-1),长度);
}
公共静态void打印列表(字符串[]列表,int位置)
{
if(位置<列表长度)
System.out.println(列表[位置]);
打印列表(列表,位置+1);
}
//有适当空间的垫板
公共静态字符串填充(字符串,整数长度)
{
字符串结果;
if(string.length()>=length)
结果=字符串;
其他的
结果=pad(“+string+”,长度);
返回结果;
}
}

您需要一个条件来停止递归。如果
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)
{

控制台中的输出

4
abcdefgh
3
 abcfgh 
2
  abgh  
1
   ab  

你做递归只是为了减少参数中的术语。这不是递归的好用法(在为尾部递归优化的函数编程语言之外),最好使用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);
    }
}
publicstaticvoidtriangleprint(字符串){
三角打印(字符串,0);
}
公共静态无效三角形打印(字符串、整型填充){
for(int i=0;i2){
int midpoint=string.length()/2;//假定字符串长度为偶数
三角形打印(字符串.子字符串(0,中点-1)+字符串.子字符串(中点+1),填充+1);
}
}

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

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

publicstaticvoidsolve(字符串字){
求解(字,0);
}
公共静态void solve(字符串字,int-it){
//打印起始空格
for(int i=0;i2){
int newlengthperside=(word.length()-2)/2;
求解(word.substring(0,newlengthperside)+word.substring(word.length()-newlengthperside),it+1);
}
}
要理解这段代码,首先看一下main方法。我们有一个for循环,它根据传递给方法的变量,在字符串之前打印出一定数量的空格,然后打印出字符串,然后打印出新行。之后,我们确定字符串的长度是否尚未结束,然后取新字符串的左侧和右侧,然后再次调用该方法。一旦字符串少于或等于2个字符,此递归将终止

我们还通过使用另一个只接受一个单词的解来重载该方法,并使用该单词和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);
}
publicstaticvoidtriangleprint(字符串输入,
整数偏移){
如果(偏移量>=in.length()){//终止条件。
返回;
}
StringBuilder sb=新的StringBuilder(偏移);//用于填充。
对于(int i=0;i
稍微不同的方法可以通过更充分地利用递归进行填充来进一步简化。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) + " ");
}
或者(更多e
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);
}
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);
}