【问题标题】:Program to print Sierpinski triangle打印谢尔宾斯基三角形的程序
【发布时间】:2013-11-25 07:33:41
【问题描述】:

我只是在看维基百科页面,我发现了这个Sierpinski triangle

我想通过java,c,scala 等创建这个三角形。

                               1                               
                              111                              
                             11111                             
                            1111111                            
                           111111111                           
                          11111111111                          
                         1111111111111                         
                        111111111111111                        
                       1               1                       
                      111             111                      
                     11111           11111                     
                    1111111         1111111                    
                   111111111       111111111                   
                  11111111111     11111111111                  
                 1111111111111   1111111111111                 
                111111111111111 111111111111111                
               1                               1               
              111                             111              
             11111                           11111             
            1111111                         1111111            
           111111111                       111111111           
          11111111111                     11111111111          
         1111111111111                   1111111111111         
        111111111111111                 111111111111111        
       1               1               1               1       
      111             111             111             111      
     11111           11111           11111           11111     
    1111111         1111111         1111111         1111111    
   111111111       111111111       111111111       111111111   
  11111111111     11111111111     11111111111     11111111111  
 1111111111111   1111111111111   1111111111111   1111111111111 
111111111111111 111111111111111 111111111111111 111111111111111

我只是创建简单的程序,就像我们在c 中创建简单模式一样,我在scala 中写了这个

def ft(n: Int) = {
    for (i <- 1 to n) {
      for (j <- n to i by -1) {
        print(" ")
      }
      for (k <- 1 to 2 * i - 1) {
        print("1")

      }
      print("\n")
    }
  }

打印这个

           1
          111
         11111
        1111111
       111111111

还有这个:

def triangle = {
    for (i <- 1 to 5) {
      for (j <- 1 to 5) {
        if (j <= i)
          print("1")
        else
          print(" ")
      }
      for (j <- 5 to 1 by -1) {
        if (j <= i)
          print("1");
        else
          print(" ");
      }
      print("\n");
    }
  } 

如何创建这个谢尔宾斯基三角形

给我解决这个问题的想法?

【问题讨论】:

  • 您已标记 5 种语言。您需要哪种语言的解决方案?
  • 我只是在寻找logic 来解决这个三角形。您可以提供任何语言
  • 逻辑是使用递归。每个三角形可以分成四个较小的三角形。将中间一个留空,然后在其他三个上递归调用自己。在某个任意点停止递归并使用您的例程绘制法线三角形。
  • @RahulKulhari:你使用的工具确实倾向于“color”你用来解决这个问题的方法。例如,Java 是一种纯面向对象的语言,而 C 则不是面向对象的。在 Scheme/lisp 中解决这个问题将是一个全功能的努力,JavaScript 也是如此,而使用 Perl 将产生代码高尔夫风格的答案......

标签: java c algorithm scala logic


【解决方案1】:

我不知道 Scala 或 Java,但似乎这门语言对你来说并不重要。这是 PostScript 中的一个解决方案:

%PS-Adobe 3.0

/Sierp {    % x1 y1 x2 y1 x3 y3 depth
    13 dict begin
        /D exch def
        /Y3 exch def
        /X3 exch def
        /Y2 exch def
        /X2 exch def
        /Y1 exch def
        /X1 exch def

        D 0 le {
            newpath
            X1 Y1 moveto
            X2 Y2 lineto
            X3 Y3 lineto
            fill
        } {
            /X12 X1 X2 add 0.5 mul def
            /Y12 Y1 Y2 add 0.5 mul def
            /X23 X2 X3 add 0.5 mul def
            /Y23 Y2 Y3 add 0.5 mul def
            /X31 X3 X1 add 0.5 mul def
            /Y31 Y3 Y1 add 0.5 mul def

            X1 Y1 X12 Y12 X31 Y31 D 1 sub Sierp
            X12 Y12 X2 Y2 X23 Y23 D 1 sub Sierp
            X31 Y31 X23 Y23 X3 Y3 D 1 sub Sierp
        } ifelse

    end
} bind def

/Sierpinski {   % xc yc radius depth
    4 dict begin
        /D exch def
        /R exch def
        /Y exch def
        /X exch def

        X
        Y R add
        X 0.8333 R mul add
        Y -0.5 R mul add
        X -0.8333 R mul add
        Y -0.5 R mul add
        D
        Sierp
    end
} bind def

300 400 250 6 Sierpinski
showpage

【讨论】:

    【解决方案2】:

    有多种方法可以通过巧妙的方式构建索引,如预期的那样在某处涉及 2 的幂,但与往常一样,python 具有最清晰的表示之一,尽管有些落后

    def sierpinski(n):    
      d = ["*"]    
      for i in xrange(n):        
        sp = " " * (2 ** i)        
        d = [sp+x+sp for x in d] + [x+" "+x for x in d]    
    return d 
    
    print "\n".join(sierpinski(4))
    

    诀窍是要意识到它不是打印构成三角形的 * 而是所有空格,将代码中的“”更改为“c”,您将看到以下内容。想法是它从一个基本模式开始并不断附加到它的头部和尾部,所以你从 2 个元素开始,然后是 4 个,然后是 8 个,最后是 16 个。由于 python 打印带有换行符的列表,你自然会得到你正在寻找的模式。

    sp is c
    ['c*c', '*c*']
    
    
    sp is cc
    ['ccc*ccc', 'cc*c*cc', 'c*ccc*c', '*c*c*c*']
    
    
    sp is cccc
    ['ccccccc*ccccccc', 'cccccc*c*cccccc', 'ccccc*ccc*ccccc', 'cccc*c*c*c*cccc', 'ccc*ccccccc*ccc', 'cc*c*ccccc*c*cc', 'c*ccc*ccc*ccc*c', '*c*c*c*c*c*c*c*']
    
    
    sp is cccccccc
    ['ccccccccccccccc*ccccccccccccccc', 'cccccccccccccc*c*cccccccccccccc', 'ccccccccccccc*ccc*ccccccccccccc', 'cccccccccccc*c*c*c*cccccccccccc', 'ccccccccccc*ccccccc*ccccccccccc', 'cccccccccc*c*ccccc*c*cccccccccc', 'ccccccccc*ccc*ccc*ccc*ccccccccc', 'cccccccc*c*c*c*c*c*c*c*cccccccc', 'ccccccc*ccccccccccccccc*ccccccc', 'cccccc*c*ccccccccccccc*c*cccccc', 'ccccc*ccc*ccccccccccc*ccc*ccccc', 'cccc*c*c*c*ccccccccc*c*c*c*cccc', 'ccc*ccccccc*ccccccc*ccccccc*ccc', 'cc*c*ccccc*c*ccccc*c*ccccc*c*cc', 'c*ccc*ccc*ccc*ccc*ccc*ccc*ccc*c', '*c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*']
    
    
    ccccccccccccccc*ccccccccccccccc
    cccccccccccccc*c*cccccccccccccc
    ccccccccccccc*ccc*ccccccccccccc
    cccccccccccc*c*c*c*cccccccccccc
    ccccccccccc*ccccccc*ccccccccccc
    cccccccccc*c*ccccc*c*cccccccccc
    ccccccccc*ccc*ccc*ccc*ccccccccc
    cccccccc*c*c*c*c*c*c*c*cccccccc
    ccccccc*ccccccccccccccc*ccccccc
    cccccc*c*ccccccccccccc*c*cccccc
    ccccc*ccc*ccccccccccc*ccc*ccccc
    cccc*c*c*c*ccccccccc*c*c*c*cccc
    ccc*ccccccc*ccccccc*ccccccc*ccc
    cc*c*ccccc*c*ccccc*c*ccccc*c*cc
    c*ccc*ccc*ccc*ccc*ccc*ccc*ccc*c
    *c*c*c*c*c*c*c*c*c*c*c*c*c*c*c*
    

    【讨论】:

      【解决方案3】:

      我用 JavaScript 编写了谢尔宾斯基三角形程序。此 JavaScript 代码在 Chrome 中运行。

      Sierpinski triangle 。要查看代码,请单击右上角的链接“在 JsFiddle 中编辑”。这里的想法是生成数据,然后为每个数字绘制圆圈。

      function Triangle() {}
      
      Triangle.prototype.height = function () {
          return this.data.length;
      }
      
      Triangle.prototype.scale = function scale(ctx, height) {
          ballsfits = this.canvas.width / 2;
          ballsgot = height;
          var scale = ballsfits / ballsgot;
          ctx.scale(scale, scale);
          return scale;
      }
      
      Triangle.prototype.init = function () {
          this.canvas = gCanvas();
          var ctx = this.canvas.getContext("2d");
          this.canvas.width = this.canvas.width; //clear
          ctx.strokeStyle = "#000";
          return ctx;
      }
      
      Triangle.prototype.generate = function (height) {
          //init
          this.data = new Array();
          this.data.push([1]);
          this.data.push(new Array(1, 1));
      
          for (var i = 2; i < height; i++) {
              var cRow = [1];
              // add each two members of preceeding row
              for (var j = 0; j < this.data[i - 1].length - 1; j++)
              cRow.push((this.data[i - 1][j] + this.data[i - 1][j + 1]) % 2);
              cRow.push(1);
              this.data.push(cRow);
          }
      }
      
      Triangle.prototype.draw = function () {
          var h = this.height();
          var ctx = this.init();
          var scale = this.scale(ctx, h);
          for (var y = 0; y < h; y++)
          for (var x = 0; x < this.data[y].length; x++)
          if (0 != this.data[y][x]) {
              ctx.beginPath();
              ctx.arc(h - this.data[y].length + x * 2 + 1, y * 2 + 1, 1, 0, Math.PI * 2);
              ctx.fill();
          }
      }
      

      代码不使用大数字。唯一需要的信息是这个数是否能被 2 整除。所以使用 0、1 和:

      (this.data[i - 1][j] + this.data[i - 1][j + 1]) % 2
      

      减少了计算时间

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多