假设有这样一个题目,用程序打印出一个圆形。
打印一个图形,从刚开始学C语言时,讲到循环那里是必做的题目了,主要有打印一个正三角,打印一个倒三角,还见过一个倒三角下面是一个正三角的图形,这些用for循环都能很好的实现,比如下面两个图形*
* *
* * *
* * * 
* *
*现在说回这个题目,是打印一个圆形,特殊性在于圆,按照一般规律想,从第一行开始,有圆周围的点的地反,就打印一个* ,可是关键在于圆的特殊性,把打印这种题目再抽象一下,无非就是打印一个空格,或者打印一个* ,从第一行扫描到最后一行就成了一个由空格或者*构成的矩形或者正方形,然后在这个矩形里找到相应图形的点,三角形的话,肯定是可以找到这样的点的,想象一下,圆形的话,是没法找到这样的点,当这个有空格和*构成的正方形无限大时,圆边的点才能无限接近于正方形当中的每个点。
或者换一种描述方式,当把圆的横向平均分成n份的话,纵向的n份肯定不是平均的,纵向的坐标肯定是一个小数,当这个正方形无限大时,那么可以找到越接近这个小数的一个自然数,这样就可以找到坐标了
程序如下:public class PrintCircle {  public static void main(String[] args) {
    int n=1000;//n越大,才能越接近圆
    PrintCircle p = new PrintCircle();
    for(int i=0;i<2*n;i++){
      p.printPoint(n,i);
    }
  }
  
  private int[] getXFromY(int y,int n)//n为半径,y<2n,返回2个x
  {
    if(y<=n){//上半侧
      int x1=n-(int)Math.sqrt(n*n-(n-y)*(n-y));
      int x2=(int)Math.sqrt(n*n-(n-y)*(n-y))+n;
      return new int[]{x1,x2};
    }
    else if(y<=2*n){//下半侧
      int x1=n-(int)Math.sqrt(n*n-(n-y)*(n-y));
      int x2=(int)Math.sqrt(n*n-(n-y)*(n-y))+n;
      return new int[]{x1,x2};
    }
    return null;
  }
  
  private void printPoint(int n,int y){//半径n,在(x,y)的位置打印一个*
      int x1=getXFromY(y,n)[0];
      int x2=getXFromY(y,n)[1];
      for(int i=0;i<=2*n;i++){
        if(i==2*n) System.out.println("\n");
        if(i==x1||i==x2) System.out.print("*");
        else System.out.print(" ");
    }
  }
}
我试了一下,n=1000,这个才大概像个圆,n小的话,一般看着大概像个椭圆
如果谁有更好的算法,请告知