分类目录归档:程序生活

Program Life – Web

【转】用JS在正方形方框内打印一个圆

转载自:[url=http://fujiangyun.com.cn/article_view.asp?id=41]http://fujiangyun.com.cn/article_view.asp?id=41[/url]
本题目源自我之前写的一篇日志:[url=http://www.ldsea.cn/java_PrintCircle/]http://www.ldsea.cn/java_PrintCircle/[/url]
付兄用js实现了该算法
[code]
<!–
程序功能:利用js在一个方框内打印一个圆
程序制作:付江云
算法来源:梁栋
说明:本程序中相关的html和js编程不重要,重要的是希望大家能理解到这个算法,利用这种方式打印一个纵向100个点的实验需要执行近15秒,网页打开时打开会卡会儿后出现一个圆,除了上下两头比较稀疏,其他地方点看起来都还密集。
测试环境:T5450 @1.66GHZ,1G内存
–>
<html>
<head>
<title>用JS在正方形方框内打印一个圆</title>
<!–下面定义打印点的颜色–>
<style>
.dian{background-color:red;}
</style>
</head>
<body>
<script>
<!–
//定义几个需要用的变量,x1和x2是横线和圆的两个交点,y是定义的纵向坐标数,borderwidth是整个正方形的边框厚度,danwei是每个点的象素,banjing是以象素为单位的半径值。
var x1,x2,y,borderwidth=1,danwei=1,banjing=100;

//定义画园主函数,主要功能有画一个边框,以及在每一行根据圆的方程计算出圆上的两点横坐标,并且调用huadian()函数将两点用生成红色span块的方式“打印”出来,如此循环直到打印完所有行的点,结束。
function huanyuan()
{
bw=2*(banjing*danwei+borderwidth);
        bh=2*(banjing*danwei+borderwidth);
document.body.innerHTML+='<div id=MainMap style=position:absolute;left:'+(document.body.clientWidth-bw)/2+';top:'+(document.body.clientHeight-bh)/2+';width:'+bw+';height:'+bh+';border-width:'+borderwidth+';border-style:outset;border-color:#00ff00></div>';
for(y=0;y<2*banjing;y++)
{
  x1=parseInt(banjing-Math.sqrt(banjing*banjing-(y-banjing)*(y-banjing)));
  x2=parseInt(banjing+Math.sqrt(banjing*banjing-(y-banjing)*(y-banjing)));
  huadian(x1*danwei,y*danwei);
  huadian(x2*danwei,y*danwei);
}
}

//定义画点函数,根据传递过来的参数确定生成的span块(即圆上的点)的位置。
function huadian(zuo,gao)
{
MainMap.innerHTML += '<span style=position:absolute;left:'+zuo+';top:'+gao+';width:'+danwei+';height:'+danwei+';overflow:hidden class=dian></span>';
}
onload=huanyuan;//窗口加载时运行画圆主函数。
//–>
</script>
</body>
</html>
[/code]
下面的图是我运行后的截图
[img][attach]176[/attach][/img]
一个很标准的圆。
这时,可能有人会问了,原先那个java的算法,要1000个点才大概像个圆,即使是1000了也没有像这个js函数画的圆标准,这段js,纵向只有100个点,如上图所示,就已经相当圆了
关键地方就在于画点的方式不一样,我在用java程序实现时,用的是System.out.println(),这个打出的一个空格或者*号,这样占据的一个字符的位置。而付兄在这段js代码中,用的画点的方式如下:
[code]function huadian(zuo,gao)
{
MainMap.innerHTML += '<span style=position:absolute;left:'+zuo+';top:'+gao+';width:'+danwei+';height:'+danwei+';overflow:hidden class=dian></span>';
}[/code]
是用html中的像素点描述的,这样一个点其实只占一个像素点,这样的话,不需要很大的半径,就可以画出很精细的圆形了:)

40 个轻量级 JavaScript 库 (下)

流行的 JavaScript 库不胜枚举,jQuery, MooTools, Prototype, Dojo, YUI。这些 JavaScript 库功能丰富,加上它们的插件,几乎能胜任任何工作,然而这是有代价的,这些库往往导致你的网页尺寸臃肿。在某些场合,如果你只想完成特定的工作,可以使用一些功能更专一的轻量库,本文介绍了40个非常出色的轻量级 JavaScript 库。

这是本文的第二部分,第一部分参见40 个轻量级 JavaScript 库 (上)

5. 字符串与数学函数

Date.js
和日期打交道不是件容易事,有很多格式要处理。Datejs 可以很好地处理简单或复杂的日期函数。可以将日期解析出诸如“Next thursday”,“+2 years”一类的格式,也支持所有日期形式,如 2009.01.08, 12/6/2001。

Datejs

Sylvester
一个处理矢量和点阵的数学 JavaScript 库,包含多维矢量和点阵建模类,以及在3D空间的一些模型。

Sylvester

Pretty Date
一个很出色的 JavaScript 库,用一种很漂亮,很友好的方式显示日期,如下图所示。

Pretty Date

XRegExp
JavaScript 中的 RegExp 对象已经支持正则表达式,XRegExp 增加了更多未来浏览器可能包含的功能(ECMAScript 4 – ES4)。该库对 RegExp 对象进行缓存,重用并增加了众多新功能。

JavaScript URL Library
一个用来处理 URL 的 JavaScript 库,可以对 URL 中的任意部分进行处理。

6. Fonts

typeface.js
这个库可以让你在网页中使用任意字体,但和 sIFR 以及 FLIR 这些基于 Flash 的方案不一样,typeface.js 100% 基于 JavaScript,只需将你的字体文件上传到一个基于 Web 的生成器那里,再将生成的 JavaScript 文件下载回来包含到网页中即可。

Typeface.js

Cufón
和 typeface.js 很相像,Cufón 也可以让你在网页中使用任意字体,同样,它也是使用一个生成器,将字体转换成 VML,将生成的 .js 文件包含到网页即可。

7. 调试与记录

Blackbird
人们经常使用 Alert() 调试 JavaScript 程序,Blackbird 提供了一个漂亮的控制台记录,查看,过滤程序的运行。

Blackbird

NitobiBug
基于浏览器的跨浏览器 javaScript 对象记录与检查工具。

NitobiBug

Firebug Lite
目前最好的 JavaScript 调试工具非 Firebug 莫属,然而该工具只支持 FireFox,将 Firebug Lite .js 文件插入你的网页,就可以在所有浏览器都实现 FireBug 功能。

Firebug Lite

8. 其它

swfobject
这是一个最受欢迎的对 Flash 对象进行引用的方法。可以生成标准 swf 引用代码,并探测用户播放器版本。如果用户版本不支持,会显示备用内容。

swfobject

sorttabledragtable
不管你喜欢与否,table 仍然是最好的表现数据的方式,但可以更好地利用。sorttable 可以让表格数据排序,只需在 table 上加一个 class="sortable" 标志,还可以排除指定的栏。dragtable 让表格的栏可以拖动,在表格上加上 class="dragable" 标志即可,这两个类可以结合起来使用,只需加上 class="sortable dragtable" 即可。

DD_roundiesDD_belatedPNG
DD_roundies 可以不依赖图片实现圆角功能,只面向 IE, 通过 VML 实现,其它浏览器会被略过,因为那些浏览器本身支持 CSS 圆角。

JavaScript Rounded Corners

DD_belatedPNG 是为了解决 IE6 对 PNG 支持不好问题而开发的,不管 PNG 图片用于 src 还是 background-image,DD_belatedPNG 都能提供修补。

Custom JavaScript Dialog Boxes
一个只有 4.5K 的轻量 JavaScript 库,可以创建用户定制对话框,可显示4种类型的消息框,alerts, warnings, prompts, success。可以设定消息框标题,内容,以及过多长时间显示。

Custom Dialog Boxes

GameJS
GameJS 是微软的 XNA 游戏框架在 JavaScript 上的移植,使用 canvas 对象作为输出设备。JavaScript 不是最佳游戏平台,但对那些帧率较低的游戏也没有问题。

GameJS

Shortcuts.js
从 Google Reader 和 Gmail 开始,Web 程序中的快捷键开始流行起来。Shorcuts.js 让快捷键的处理变得简单。

Mapstraction
有不少地图提供商都提供不同 API,如果你要更换提供商,比如从 Google Maps 到 MapQuest,需要更新代码,Mapstraction 提供了常用地图提供商的 API,只需该一行代码就能完成转换。

Mapstraction

Amberjack
一个只有 4K 的微型 JavaScript 库,可以为你的网站添加漂亮的教程功能,一个模式窗口会以教程的形式显示任意内容,教程中的步骤可以通过手工编码实现或在线自动生成。可以使用主题或 CSS 控制内容的格式。

Amberjack

JsLoad
JsLoad 可以从 Google server 远程加载各种 JavaScript 库,可以自动加载各种版本的支撑库。

本文国际来源:http://www.smashingmagazine.com/2009/03/02/40-stand-alone-javascript-libraries-for-specific-purposes/
中文翻译来源:COMSHARP CMS 官方网站

40 个轻量级 JavaScript 库 (上)

流行的 JavaScript 库不胜枚举,jQuery, MooTools, Prototype, Dojo, YUI。这些 JavaScript 库功能丰富,加上它们的插件,几乎能胜任任何工作,然而这是有代价的,这些库往往导致你的网页尺寸臃肿。在某些场合,如果你只想完成特定的工作,可以使用一些功能更专一的轻量库,本文介绍了40个非常出色的轻量级 JavaScript 库。

1. 表单相关

wForms
一个低调的开源项目,简化了绝大多数常用 JavaScript 表单功能,包含可以直接使用的表单验证功能,另外,还包含强大的表单同步以及表单条件判断功能。

wForms

Validanguage
又一个低调的 JavaScript 表单验证框架。它拥有集成逻辑,一些设置可以针对全局,单个表单或单个对象。提供两个API,集成 AJAX 支持,缓存,以及回调函数。它提供类似 HTML 的 API 语句,以及面向对象的 JavaScript API 。

Validanguage

LiveValidation
一个轻量的表单验证库。除了传统的验证功能,还提供实时验证,可以一边输入一遍验证。Ruby on Rails 用户可能会发现这个库非常好用,因为他们的命名规则和参数十分近似。该库既有独立版本,又有一个 Prototype 版本。

LiveValidation

yav
一个强大,灵活,可扩展的表单验证库。支持各种场合,从简单的如日期,电子邮件地址以及整数的验证,到复杂的,如正则表达式。内置 AJAX 支持,输出的错误消息可以定位到对象级。

qForms
处理表单的整套方案。功能包括各种验证规则,防止多次发布的机制,以及锁定或解锁制定输入框。

formreform
不基于 table 的多栏设计向来是一个挑战。这个微型库将传统的表单变成漂亮的多栏形式。formreform

2. 动画相关

$fx()
一个用来让 HTML 对象运动的轻量库。你可以在一个时间轴上改变任何 CSS 属性,对于复杂动画,你可以将各种效果结合起来,将对象分组,让它们并行运动。

$fx() JavaScript Animation Library

JSTweener
一个生成中间帧的 JavaScript 库,它的 API 类似著名的中间帧引擎 Tweener。你可以指定动画时间,定义切换效果以及时延。在几乎任何点都可以触动事件。

JSTweener

Facebook Animation
一个强大的,用来创建可定制的,基于 CSS 的动画。在 Facebook 动画中,几行代码就可以改善 UI。语法和 FBJS (用于 Facebook 的库)一样。

FX
一个语法类似 YUI 的轻量 JavaScript 库,可以为几乎任何 CSS 属性创建中间帧。支持颜色和滚动动画,为对象设置 to 和 from 值就可以了。

3. 视觉与图形效果

JS charts
支持柱状图,圆饼图以及简单的曲线图。直接将这个库插入网页,然后从 XML 文件或 JavaScript 数组变量调用数据。PNG 格式,兼容所有主要浏览器。

JS Charts

Canvas 3D JS Library (C3DL)
C3DL 使 3D 程序的编写变得简单。提供一套数学,场景与 3D 对象类,可以直接在浏览器中开发 3D 内容,不需要很深的 3D 知识。

C3DL

Processing.js
这是 Processing 语言在 JavaScript 的移植。2D输出功能丰富。提供了绘图,色彩处理,字体,对象等处理函数。

Processing.js

Rapha?l
一个让人惊叹的 JavaScript 库,可以在 Web 上实现矢量图。使用 SVG, VML 创建的图形可以被更改或绑定事件。功能极其丰富,包括旋转,动画,缩放等。

Raphael: Vectors With JavaScript

ImageFX
该 JavaScript 库为图片添加效果,如虚化,锐化,浮雕,加亮等。ImageFX 使用画布对象实现这些效果,兼容所有主流浏览器。这个库非常容易使用,只要将 .js 库文件插入网页,调用那些函数即可。

Imagefx

Pixastic
Pixastic 使用 HTML5 画布对象,允许对原始像素进行操作。效果包括去饱和度,灰度级,反转,亮度,对比度调整,色调,饱和度调整,以及浮雕,虚化等效果。因为用到了 HTML 5 的画布对象,因此还无法兼容所有浏览器。

Reflection.js
一个很低调的 JavaScript 自动实现倒影效果。倒影的高度,透明度可以调整。支持所有主流浏览器,文件尺寸小于5K。

Reflection.js

4. 数据库

Taffy DB
一个 JavaScript 库,可以看作浏览器中的 SQL Server,或高级数组管理器。在使用了 AJAX 的程序中,可以用作数据库层,可以创建,读取,编辑,删除数据,使用循环,排序以及高级查询。

ActiveRecord.js
这个库支持 Google Gears 以及 Chrome,Aptana Jaxer, Adobe AIR 以及任何支持 HTML 5 SQL 细则的平台(目前有 Webkit 以及 iPhone)。可以自动创建表,验证和同步数据。

ActiveRecord.js

本文国际来源:http://www.smashingmagazine.com/2009/03/02/40-stand-alone-javascript-libraries-for-specific-purposes/
中文翻译来源:COMSHARP CMS 官方网站

【转】如何遍历Map

[code]
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* 如何遍历Map。<br>
* 第一步,得到keySet,也就是键值的集合<br>
* 第二步,循环每个键,可以用迭代器<br>
* 第三步,对每个键进行读取<br>
*
* @author 老紫竹研究室(laozizhu.com)
*/
public class Test {
  public static void main(String[] args) {
    Map map = new HashMap();
    map.put("1 ", "2 ");
    map.put("2 ", "3 ");
    Iterator i = map.keySet().iterator();
    while (i.hasNext()) {
      System.out.println(map.get(i.next()));
    }
  }
}
[/code]

一道经典的分油问题

[quote]题目要求:一个桶中有12斤油,要求倒出6斤,可现在另外只有两个桶,分别可装8斤与5斤,请问应如何来倒。补充:这里的12,6,8,5都是变量,应该可以自己设置,输出是每一次分油的步骤。[/quote]
题目可理解为对8和5进行加减,使之能产生6即可。
其中,+代表往改桶里倒满油。-代表将该桶的里油全部倒出。
此题的一个简单结果是8+8-5-5=6,这意味着,只要连续2次将8的桶灌满然后2次将5的桶灌满则8斤的桶里面剩下的刚好是6斤的油。
由此可以归纳出来算法就是找到满足x*8+y*5使之满足最后所求即可,x和y是可正可负的一个系数。
[code]
import java.util.ArrayList;
import java.util.List;

public class SplitOil {

  /**
   * 题目要求:一个桶中有12斤油,要求倒出6斤,可现在另外只有两个桶,分别可装8斤与5斤,请问应如何来倒?
   * 补充:这里的12,6,8,5都是变量,应该可以自己设置,输出是每一次分油的步骤。
   *
   * 题目可理解为对8和5进行加减,使之能产生6即可。
   * 其中,+代表往改桶里倒满油。-代表将该桶的里油全部倒出。
   * 此题的一个简单结果是8+8-5-5=6,这意味着,只要连续2次将8的桶灌满然后2次将5的桶灌满则8斤的桶里面剩下的刚好是6斤的油。
   * 由此可以归纳出来算法就是找到满足x*8+y*5使之满足最后所求即可,x和y是可正可负的一个系数。
   */
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    List<OilQuestion> resultList = new ArrayList<OilQuestion>();
    int a=8;//桶1的容量
    int b=5;//桶2的容量
    int c=6;//要求的结果
    resultList=getXY(a,b,c);
    for(int i=0;i<resultList.size();i++){
      OilQuestion o = (OilQuestion)resultList.get(i);
      System.out.println("x="+o.getA()+";"+"y="+o.getB());
    }
  }
  
  public static List<OilQuestion> getXY(int a ,int b,int result){
    //考虑到可能有多种结果,所以把结果OilQuestion放到一个List当中,每一个OilQuestion是一个由a,b系数组成的对象
    //选出一个结果 为 result=x*a+y*b ,这里的x,y可正可负
    List<OilQuestion> resultList = new ArrayList<OilQuestion>();
    int max=50;
    int x=0;
    int y=0;
    for(int i=-max;i<max;i++)
      for(int j=-max;j<max;j++){
        if((i*a+j*b)==result) {
          x=i;
          y=j;
          OilQuestion o = new OilQuestion();
          o.setA(x);
          o.setB(y);
          resultList.add(o);
          }
        else continue;
      }
        
    return resultList;
  }
}

class OilQuestion{//定义一个内部类,该内部类有两个属性a和b
  int a;
  int b;
  public void setA(int a)
  {
    this.a=a;
  }
  public void setB(int b)
  {
    this.b=b;
  }
  public int getA(){
    return a;
  }
  public int getB(){
    return b;
  }
}
[/code]

一个程序看java的static

[code]class StaticTest{
   int x=1;
   static int y=1;
}
class StaticTester{
  public static void main(String args[]){
    int i;
    StaticTest.y= StaticTest.y +1;
    StaticTest  m=new  StaticTest();
    StaticTest  n=new  StaticTest();
    m.x= m.x +3;
    m.y= m.y+3;
    n.x= n.x+5;
    n.y= n.y+5;
    System.out.println("m.x="+m.x+" "+ "m.y="+m.y);
    System.out.println("n.x="+n.x+" "+ "n.y="+n.y);
  }
}[/code]

输出结果为:
m.x=4 m.y=10
n.x=6 n.y=10

m.x=4和m.x=6都是好理解的

下面是一个简短的说明:
[quote]static可以修饰类中的属性和方法。
静态属性在类定义时静态地分配空间。它属于类,不属于某个特定的对象,因此可以通过类进行访问。往往将属于类的公共属性说明成static。[/quote]

也就是说一个声明为static的变量,你改变多少次,它的值只是唯一的一个,就像前面引用的说的
[quote]静态属性在类定义时静态地分配空间。它属于类,不属于某个特定的对象[/quote]
如果最后把StaticTest.y打印出的,也是10

substring各不同

js:substring(beginindex, endindex),取得是beginindex到endindex-1位置处的字符串。
java: substring(beginindex, endindex),取得是beginindex到endindex-1位置处的字符串。
c#: substring(beginindex, length),取得是beginindex开始的长度为length的字符串。

比如“0123456”
js: substring(1, 4) 为 “123”
java: substring(1, 4) 为 “123”
c#: substring(1, 4) 为 “1234”

【转】使用后缀表达式解释Java中的数学表达式(含代码实现)

  编写Java程序时,我们可能会碰到解释数学表达式的问题,例如,输入字符串“(5+4)*10”,求出其算术结果,对于这个问题,可以通过后缀表达式来解决。

        首先,让我们看看后缀表达式的算法:
1) 将中缀表达式转换为后缀表达式:
  •当读到数字直接送至输出队列中;
  •当读到运算符t时:
            a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;
   b.t进栈;
  •读到左括号时总是将它压入栈中;
  •读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号;
        •中缀表达式全部读完后,若栈中仍有运算符,将其送到输出队列中。
2) 运用后缀表达式进行计算:
  •建立一个栈S;
  •从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,读到运算符则从栈中依次弹出两个数分别到Y和X,然后以“X 运算符 Y”的形式计算机出结果,再压加栈S中;
  •如果后缀表达式未读完,就重复上面过程,最后输出栈顶的数值则为结束。

         以下是代码实现:

[code]package wenly.util;

import java.util.Stack;
import java.util.regex.*;

public class StringToArithmetic …{
    private StringToArithmetic() …{
    }

    /** *//**
     * 给出一个算术表达式,返回结果。 例如 (5+8+10)*1,返回23
     *
     * @param string
     */
    public static double stringToArithmetic(String string) …{
        return postfixExprToArithmetic(prefixExprToPostfixExpr(string));
    }

    /** *//**
     * 中缀表达式转后缀表达式
     *
     * @param String
     *            prefix
     * @return String
     */
    private static String prefixExprToPostfixExpr(String prefix) …{
        Stack<Character> stack = new Stack<Character>();
        String postfix = "";
        int length = prefix.length();
        for (int i = 0; i < length; i++) …{
            Character temp;
            char c = prefix.charAt(i);
            switch (c) …{
            // 忽略空格
            case ' ':
                break;
            // 碰到'(',push到栈
            case '(':
                stack.push(c);
                break;
            // 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
            case '+':
            case '-':
                while (stack.size() != 0) …{
                    temp = stack.pop();
                    if (temp == '(') …{
                        stack.push('(');
                        break;
                    }
                    postfix += " " + temp;
                }
                stack.push(c);
                postfix += " ";
                break;
            // 碰到'*''/',将栈中所有乘除运算符弹出,送到输出队列中
            case '*':
            case '/':
                while (stack.size() != 0) …{
                    temp = stack.pop();
                    if (temp == '(' || temp == '+' || temp == '-') …{
                        stack.push(temp);
                        break;
                    } else …{
                        postfix += " " + temp;
                    }
                }
                stack.push(c);
                postfix += " ";
                break;
            // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号
            case ')':
                while (stack.size() != 0) …{
                    temp = stack.pop();
                    if (temp == '(')
                        break;
                    else
                        postfix += " " + temp;
                }
                postfix += " ";
                break;
            default:
                postfix += c;
            }
        }
        while (stack.size() != 0)
            postfix += " " + stack.pop();
        return postfix;
    }

    /** *//**
     * 通过后缀表达式求出算术结果
     *
     * @param String
     *            postfix
     * @return double
     */
    private static double postfixExprToArithmetic(String postfix) …{
        Pattern pattern = Pattern.compile("\d+||\d+\.\d*"); // 匹配数字
        String strings[] = postfix.split(" ");
        for (int i = 0; i < strings.length; i++)
            strings[i].trim();
        Stack<Double> stack = new Stack<Double>();
        for (int i = 0; i < strings.length; i++) …{
            if (strings[i].equals(""))
                continue;
            if ((pattern.matcher(strings[i])).matches()) …{
                stack.push(Double.parseDouble(strings[i]));
            } else …{
                double y = stack.pop();
                double x = stack.pop();
                stack.push(caculate(x, y, strings[i]));
            }
        }
        return stack.pop();
    }

    private static double caculate(double x, double y, String simble) …{
        if (simble.trim().equals("+"))
            return x + y;
        if (simble.trim().equals("-"))
            return x – y;
        if (simble.trim().equals("*"))
            return x * y;
        if (simble.trim().equals("/"))
            return x / y;
        return 0;
    }
}[/code]

用java打印一个圆

今天在家呆着学习Spring,随意搜一些关于java的QQ群,加了一个,一个人问了一个题,说是用程序打印出一个圆形,打印一个图形,从刚开始学C语言时,讲到循环那里是必做的题目了,主要有打印一个正三角,打印一个倒三角,还见过一个倒三角下面是一个正三角的图形,这些用for循环都能很好的实现,比如下面两个图形

*
* *
* * *

* * *
* *
*

现在说回这个题目,是打印一个圆形,特殊性在于圆,按照一般规律想,从第一行开始,有圆周围的点的地反,就打印一个* ,可是关键在于圆的特殊性,把打印这种题目再抽象一下,无非就是打印一个空格,或者打印一个* ,从第一行扫描到最后一行就成了一个由空格或者*构成的矩形或者正方形,然后在这个矩形里找到相应图形的点,三角形的话,肯定是可以找到这样的点的,想象一下,圆形的话,是没法找到这样的点,当这个有空格和*构成的正方形无限大时,圆边的点才能无限接近于正方形当中的每个点。
或者换一种描述方式,当把圆的横向平均分成n份的话,纵向的n份肯定不是平均的,纵向的坐标肯定是一个小数,当这个正方形无限大时,那么可以找到越接近这个小数的一个自然数,这样就可以找到坐标了
程序如下:

public class PrintCircle {

 /**
  * @param args
  */
 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-(ny)*(ny));
     int x2=(int)Math.sqrt(n*n-(ny)*(ny))+n;
     return new int[]{x1,x2};
   }
   else if(y<=2*n){//下半侧
     int x1=n-(int)Math.sqrt(n*n-(ny)*(ny));
     int x2=(int)Math.sqrt(n*n-(ny)*(ny))+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小的话,一般看着大概像个椭圆

如果谁有更好的算法的话,欢迎告诉我:)

JSP中出现According to TLD or attribute directive in tag file

应用部署运行的时候出现JSP异常, 发生在使用JSTL库的时候: According to TLD or attribute directive in tag file, attribute value does not accept any expressions, 可能是因为使用了JSP2.0版本, 同时又没有使用JSTL core库的备用版本(RT库), 以下有两种处理方法:

1. 如果不想使用web-app_2_4.xsd 和jstl1.1 那么可以按照下面两种方式修改

1). 修改web.xml.

[code]<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">[/code]改为2.3版本的
[code]<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>[/code]
2). 使用JSTL core RT库

JSTL core库的有两种taglib伪指令, 其中RT库即是依赖于JSP传统的请求时属性值, 而不是依赖于EL来实现(称为EL库.JSP2.0将支持EL)

JSP中使用<%@ taglib uri=http://java.sun.com/jstl/core prefix="c"%>在2.3版本都可以,在2.4就不行了, 这是版本不兼容引起的,稍后将介绍servlet的版本。

只要将
[code]<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>[/code]
改为
[code]<%@ taglib uri=http://java.sun.com/jstl/core_rt prefix="c"%>[/code]

2:如果要使用jstl1.1(推荐) 则按照一下修改,很简单的。

jstl存在1.0和1.1的差异问题,用EL建议需要在1.1的版本下,

使用jstl1.1 只需要将

1.0的为

[code]<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>[/code]

换成:

[code]<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>[/code]

注意,1.0版本没有/jsp/

附录: jsp servlet j2ee tomcat jdk的版本差别

一 JSP2.0与JSP1.2比较

JSP 2.0是对JSP 1.2的升级,新增功能:
1. Expression Language

2. 新增Simple Tag和Tag File

3.web.xml新增<jsp:config>元素

特别说明web.xml.
web.xml新增<jsp:config>元素

<jsp-config> 元素主要用来设定JSP相关配置,<jsp-config> 包括<taglib>和<jsp-property-group>
子元素。

(1)其中<taglib>以前的Jsp1.2中就有的,taglib主要作用是作为页面taglib标签中的uri和tld文件的一个映射关系

(2)其中<jsp-property-group>是JSP2.0种新增的元素。

[code]<jsp-property-group> 主要包括8个子元素,它们分别是:

<jsp-property-group>

<description> [/code]
设定的说明

[code]</description>

<display-name>设定名称</display-name>

<url-pattern>设定值所影响的范围</url-pattern>

<el-ignored>若为true则不支持EL语法</el-ignored>

<page-encoding>ISO-8859-1</page-encoding>

<scripting-invalid> 若为true则不支持<% scripting%> 语法</scripting-invalid>

<include-prelude>设置JSP网页的抬头,扩展名为.jspf </include-prelude>

<include-coda>设置JSP网页的结尾,扩展名为.jspf</include-coda>

</jsp-property-group>[/code]

例如: 其中抬头程序:

[code]prelude.jspf
<br>
<center>
文本内容
</center>
<hr>

结尾程序:
coda.jspf
<br>
<center>
文本内容
</center>
<hr>[/code]

二、Servlet个版本比较

servlet 2.3 新增功能:
2000年10月份出来
Servlet API 2.3中最重大的改变是增加了filters

servlet 2.4 新增功能:
2003年11月份出来
1、web.xml DTD改用了XML Schema;

Servlet 2.3之前的版本使用DTD作为部署描述文件的定义,其web.xml的格式为如下所示:

[code]<?xml version="1.0" encoding="IS0-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//sunMicrosystems,Inc.//DTD WebApplication 2.3f//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.3.dtd">
<web-app>
…….
</web-app>[/code]

Servlet 2.4版首次使用XML Schema定义作为部署描述文件,这样Web容器更容易校验web.xml语法。同时XML Schema提供了更好的扩充性,其web.xml中的格式如下所示:

[code]<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:workflow="http://www.workflow.com"
xmins:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
………
</web-app>[/code]

注意: 改为Schema后主要加强了两项功能:
(1) 元素不依照顺序设定
(2) 更强大的验证机制
主要体现在:
a.检查元素的值是否为合法的值
b.检查元素的值是否为合法的文字字符或者数字字符
c.检查Servlet,Filter,EJB-ref等等元素的名称是否唯一
2.新增Filter四种设定:REQUEST、FORWARD、INCLUDE和ERROR。
3.新增Request Listener、Event和Request Attribute Listener、Enent。
4.取消SingleThreadModel接口。当Servlet实现SingleThreadModel接口时,它能确保同时间内,只能有一个thread执行此Servlet。
5.<welcome-file-list>可以为Servlet。
6.ServletRequest接口新增一些方法。
public String getLocalName()
public String getLocalAddr()
public int getLocalPort()
public int getRemotePort()

Servlet 2.5的新特征
2005年9月发布Servlet 2.5
Servlet2.5一些变化的介绍:
1) 基于最新的J2SE 5.0开发的。
2) 支持annotations 。
3) web.xml中的几处配置更加方便。
4) 去除了少数的限制。
5) 优化了一些实例

servlet的各个版本对监听器的变化有:
(1)servlet2.2和jsp1.1
新增Listener:HttpSessionBindingListener
新增Event: HttpSessionBindingEvent
(2)servlet2.3和jsp1.2
新增Listener:ServletContextListener,ServletContextAttributeListener
,HttpSessionListener,HttpSessionActivationListener,HttpSessionAttributeListener
新增Event: ServletContextEvent,ServletContextAttributeEvent,HttpSessionEvent
(3)servlet2.4和jsp2.0
新增Listener:ServletRequestListener,ServletRequestAttribureListener
新增Event: ServletRequestEvent,ServletRequestAttributeEvent

三、J2EE规范版本比较

1.J2EE的发展

1997年Servlet技术的产生以及紧接着JSP的产生,为Java对抗PHP,ASP等等服务器端语言带来了筹码。1998年,Sun发布了EJB1.0标准,至此J2EE平台的三个核心技术都已经出现。于是,1999年,Sun正式发布了J2EE的第一个版本。并与1999年底发布了J2EE1.2,在2001年发布了J2EE1.3,2003年发布了J2EE1.4。

2.J2EE1.3
J2EE1.3的架构,其中主要包含了Applet容器,Application Client容器,Web容器和EJB容器,并且包含了Web Component,EJB Component,Application Client Component,以JMS,JAAS,JAXP,JDBC,JAF,JavaMail,JTA等等技术做为基础。

1.3中引入了几个值得注意的功能:Java消息服务(定义了JMS的一组API),J2EE连接器技术(定义了扩展J2EE服务到非J2EE应用程序的标准),XML解析器的一组Java API,Servlet2.3,JSP1.2也都进行了性能扩展与优化,全新的CMP组件模型和MDB(消息Bean)。

3.J2EE1.4

J2EE1.4大体上的框架和J2EE1.3是一致的,1.4增加了对Web服务的支持,主要是Web Service,JAX-RPC,SAAJ,JAXR,还对EJB的消息传递机制进行了完善(EJB2.1),部署与管理工具的增强(JMX),以及新版本的Servlet2.4和JSP2.0使得Web应用更加容易。

四、Tomcat版本比较

Tomcat 3.x
servlet2.2和jsp1.1标准
Tomcat 4.x
Servlet 2.3 和 JSP 1.2 版本
Tomcat 5.x
Servlet 2.4或2.5 和 JSP 2.0 版本

五、JDK版本比较

已发行的版本:
版本号 名称 中文名 发布日期
JDK 1.1.4 Sparkler 宝石 1997-09-12
JDK 1.1.5 Pumpkin 南瓜 1997-12-13
JDK 1.1.6 Abigail 阿比盖尔–女子名 1998-04-24
JDK 1.1.7 Brutus 布鲁图–古罗马政治家和将军 1998-09-28
JDK 1.1.8 Chelsea 切尔西–城市名 1999-04-08
J2SE 1.2 Playground 运动场 1998-12-04
J2SE 1.2.1 none 无 1999-03-30
J2SE 1.2.2 Cricket 蟋蟀 1999-07-08
J2SE 1.3 Kestrel 美洲红隼 2000-05-08
J2SE 1.3.1 Ladybird 瓢虫 2001-05-17
J2SE 1.4.0 Merlin 灰背隼 2002-02-13
J2SE 1.4.1 grasshopper 蚱蜢 2002-09-16
J2SE 1.4.2 Mantis 螳螂 2003-06-26
J2SE 5.0 (1.5.0) Tiger 老虎

J2SE 5.1 (1.5.1) Dragonfly 蜻蜓

J2SE 6.0 (1.6.0) Mustang 野马