Javascript高效模式打印

Javascript effiecient pattern print

本文关键字:式打印 模式 高效 Javascript      更新时间:2023-09-26

我想打印如下:

5 5 5 5 5
 4 4 4 4
  3 3 3
   2 2
    1
   2 2
  3 3 3
 4 4 4 4
5 5 5 5 5

我能够使用2 for循环到达模式的上半部分。

print(5);
function print(n) {
    for(i=n;i>=1;i--) {
        for(j=1;j<=i;j++) {
            console.log(i+" ");
        }
         console.log("<br>");   
    }
}

请参阅http://jsfiddle.net/5k8jLgmo/进行现场演示
console.log更改为document.write

问题1-如何打印反射?我可以使用另一个类似的循环。但还有更有效的方法吗?

问题2-为了打印前半部分,我用2表示循环。它能用O(n)完成吗?

问题3-如何使用document.write'n'空间
例如,如果我必须打印"face book"(单词之间有3个空格)
如何完成
基本上它不是简单的CCD_ 5,而是空间基于循环的第i个值而不断变化。

具有1个JavaScript循环的解决方案,
但是Array()构造函数、.join().reverse()方法是内部循环,这意味着它们通常运行得更快。

版本1至9:

function hourGlassString(n) {
    if (n<2) return '1';
    var r=[], out='', org=n, pad='';
    while (n>0) {
        pad=Array(org - n + 1).join(' ');
        r.push(pad + Array(n).join(n + ' ') + n + pad);
        n--;
    }
    out=r.join("'n");
    r.pop();
    out+="'n" + r.reverse().join("'n");
    return out;
}
console.log(hourGlassString(9));

输出:

9 9 9 9 9 9 9 9 9
 8 8 8 8 8 8 8 8 
  7 7 7 7 7 7 7  
   6 6 6 6 6 6   
    5 5 5 5 5    
     4 4 4 4     
      3 3 3      
       2 2       
        1        
       2 2       
      3 3 3      
     4 4 4 4     
    5 5 5 5 5    
   6 6 6 6 6 6   
  7 7 7 7 7 7 7  
 8 8 8 8 8 8 8 8 
9 9 9 9 9 9 9 9 9

版本高达99:

function hourGlassStringE(n) {
    if (n<2) return '1';
    var r=[], out='', org=n, pad='';
    while (n>0) {
        var s=' ';
        pad=Array(org - n + 1).join(s);
        if (n<10 && org>9) s=s + s;
        r.push(pad + Array(n).join(n + s) + n + pad);
        n--;
    }
    out=r.join("'n");
    r.pop();
    out+="'n" + r.reverse().join("'n");
    return out;
}
console.log(hourGlassStringE(13));

输出:

13 13 13 13 13 13 13 13 13 13 13 13 13
 12 12 12 12 12 12 12 12 12 12 12 12 
  11 11 11 11 11 11 11 11 11 11 11  
   10 10 10 10 10 10 10 10 10 10   
    9  9  9  9  9  9  9  9  9    
     8  8  8  8  8  8  8  8     
      7  7  7  7  7  7  7      
       6  6  6  6  6  6       
        5  5  5  5  5        
         4  4  4  4         
          3  3  3          
           2  2           
            1            
           2  2           
          3  3  3          
         4  4  4  4         
        5  5  5  5  5        
       6  6  6  6  6  6       
      7  7  7  7  7  7  7      
     8  8  8  8  8  8  8  8     
    9  9  9  9  9  9  9  9  9    
   10 10 10 10 10 10 10 10 10 10   
  11 11 11 11 11 11 11 11 11 11 11  
 12 12 12 12 12 12 12 12 12 12 12 12 
13 13 13 13 13 13 13 13 13 13 13 13 13

内置左+右填充;

为了回答您的第三个问题,html将所有空格折叠为一个空格。为了解决这个问题,您可以使用&nbsp;'u2000 )或其他空白。和element.innerHTML而不是document.write

function print(n) {
    for(i=n;i>=1;i--) {
        for(j=i;j<=n;j++) document.write("&nbsp;");
        for(j=1;j<=i;j++) {
            document.write(i+" ");
        }
        document.write("<br>");   
    }
    for(i=2;i<=n;i++) {  // This needs to be n
        for(j=i;j<=n;j++) document.write("&nbsp;");
        for(j=1;j<=i;j++) {
            document.write(i+" ");
        }
        document.write("<br>");   
    }
}

不确定效率本身,但肯定是一种比for循环负载更干净的方法(在我看来):

function hourglassNum(n)
{
  var num,i,j=0,k=0,str=''; 
  for(i=1; i<(n*2) ; i++, str='', j=0, k=0)
  {
    num = Math.abs(i-n)+1;
    while(j++ < n - num) str += ' ';
    while(k++ < num) str += ' '+num;
    console.log(str);
  }
}
hourglassNum(5);

它包括循环两倍的目标数字,并通过计算循环索引与中间目标数字的差异来更改循环内的可打印数字:Math.abs(i-n)。然后,我们在其中添加1,以避免循环为4->0。完成后,只需执行一些简单的while循环即可添加空格和可打印数字。

更新:事实证明这在性能方面是相当不错的。目前超过了您现有的不完整代码和当前的其他解决方案:JSPerf测试

如何打印反射?

只需反向运行你的外循环(过线的那个)。

我可以使用另一个类似的循环。但还有更有效的方法吗?

如果你关心代码重复,那么使用一个函数来抽象它——一个只用于内部循环,或者一个用于指定方向的外部循环。

当然,您可以将第一行存储在数组中,打印它,.reverse(),然后再次打印出来,但这会导致空间效率低下。

为了打印前半部分,我用2表示循环。它能用O(n)完成吗?

否,不能在O(n)中打印n²个字符。两个嵌套循环非常好,它们使用恒定的空间和最小的时间。