2009年5月7日星期四

JavaScript判断输入框是否为浮点数

今天遇到了这样一个问题,我们在进行验证一个文本输入框中输入的数据是不是有效的浮点数时,刚开始准备用 if(!(parseFloat(sNumber)))或者if(isNaN(parseFloat(sNumber)))进行判断,后来却发现这个parseFloat竟然在你输入的sNumber中有数字,也有非法字符的时候,将其中的有效数字留下来,其余的全部丢掉,这样它返回的就不再是NaN了,这样我的判断就是错误的了,所以不得不自己去写一个function来判断输入的是否为浮点数。

最开始想的方法就是用正则表达式,自己写了一个简单的测试浮点数的正则表达式:如下


function checkFloat(str)
{
var regexFloat = /^(\-){0,1}[0-9]{1,5}\.{0,1}[0-9]+$/;
if(regexFloat.test(str))
{
alert('true');
return true;
}
else
{
alert('false');
return false;
}
}
checkFloat("-234.5");
checkFloat("0.3423");
checkFloat("1234");
checkFloat("--1234");
checkFloat("12.3.4");


以上只是一个最最初步的检测,实际上还是有很多问题的,比如“001”这种有多余零的情况会被判断正确,这个就很不爽了,必须又加几条if语句进行判断,比较不爽。实验室另外一位同学采用了String对象中的一些方法也解决这个判断Float的类型,我觉得还是有点过于复杂。这是突然想骂骂这个parseFloat,它为什么要这样做呢,有非法字符返回个NaN岂不是很好的事情吗,突然灵光一亮,我想到一个更简单的方法。
既然parseFloat会丢弃其中的一部分不合法字符,那我们何不就利用它的这个性质进行Float类型的判断呢? 代码如下:


function checkFloat(sNumber)
{
var nFloatNum = parseFloat(sNumber);
if(nFloatNum.toString() != sNumber)
{
return false;
}
else
{
return true;
}
}



至此问题比较简单的解决了。原来有时候一个方法的“缺点”也可以好好利用。^_^

……

[阅读全文]

2009年4月25日星期六

xsl递归

昨天晚上我们项目组的一个同学希望我将我们的配置页面的列表修改一下,他提出了两个要求:

1、在传给我们一些字符串时,要是不传东西我们,我们列表中要显示未绑定,传的字符串过长时,要显示其中的一部分,后面内容省略。

2、有一个列表的显示值的底层本应发字符串给我们的,他们却是发一个ulong的数字给我,其中从最低位到从左往右第四位,分别表示的一种状态,这样一组合就有16种情况,要我们上层去将数字转化为相应的页面显示。

第一个问题比较简单,我们在写自定义列的时候,用xpath的一个函数string-length去获取字符串的长度,然后再用<xsl:choose>判断一下就可以了,代码如下:

<xsl:choose>

<xsl:when test="string-length($str) > 14"><!--$str可以使xpath路径-->

<xsl:value-of select="substring($str,1,14)"/>

<xsl:value-of select="'...'"/>

</xsl:when>
<xsl:when test="string-length($str) = 0">

<xsl:value-of select="xpath"/>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="$str"/>

</xsl:otherwise>

</xsl:choose>


第二个问题就比较麻烦了,(要是用C,就相当简单了,可是对于我们页面上来说,还是不那么容易的)看到第二个问题,我想到的方法有两种,第一种,用js获取值,然后进行转化,在动态的赋给每一个table中的那一列数据。用js写的话,会比较容易,基本语法和C一样,在页面加载后调用的初始化函数中去初始化那些显示值,这样首先用js去存储这么多数据就是一种浪费空间,然后就是对于行数比较多的,这个也会降低速度。那么就自然的引出了第二个方法,用xsl,结合xpath的方法和它的一些逻辑函数,这个实际上也是包含两种方法的,一是用xml将16种情况的显示值全部列出来,然后到时候通过取集合中的元素的方法就可以了,我个人不太喜欢这样做,因为不通用,要是有一个状态位数更多的情况就又得修改。于是我选择的是让xml存储的是每一位所代表的状态字符,然后通过判断传上来的ulong数据,对这些数据进行组装。

所以,一开始我就决定了用最后一种方法,今天刚调试出来,我是怎么做的呢?


我刚开始试过用<xsl:variable>去存储那些ulong值,然后通过修改变量的值来处理的方法,空口说不好,写出下段代码帮助理解:

<xsl:variabe name="str" select="''"/><!--str用于存储转化后的字符-->

<xsl:variable name="num" select="."/><!--用num变量存储那个ulong型数的值-->

(xsl和xpath中没有移位这种操作)下面的逻辑用伪码表示

if($num-8>0){$num = $num-8; $str = $str+"相应字符串"}

if($num-4>0){$num = $num-4; $str = $str+"相应字符串"}

if($num-2>0){$num = $num-2; $str = $str+"相应字符串"}

if($num-1>0){$num = $num-1; $str = $str+"相应字符串"}

至此,str就保存了完整的转换后的字符串了。

想的很轻松,写成了之后,页面什么显示都没有,在调试了不少时间,发现了原来xsl中的变量是不允许改变的。这个实在是有点“没人性”,好端端的变量名,只允许一次赋值,又不能够改变,这算什么变量嘛,干脆叫宏、常量得了,^_^

这下我就晕掉了,变量竟然不能够改变,我们如何处理呢,岂不就是宣告此路不通,这时,想到了强大的call-template,apply-templates这些类似函数的东东。

竟然通过变量改变搞不定,我也来学学我们这个项目中随处可见的call-template,
apply-templates这样的东西,用递归来帮助解决问题。

先把调用代码的主体copy看看

<xsl:variable name="str">

<xsl:call-template name="findGlobleString">

<xsl:with-param name="num" select="$num"/><!--要转化的ulong型的数字-->

<xsl:with-param name="step" select="'8'"/> <!--解析开始的最高位,二进制"1000”-->

<xsl:with-param name="maxstep" select="'16'"/><!--能够解析数字的上限+1-->

</xsl:call-template>

</xsl:variable>

下面我将template用伪码写出来,便于理解,更加简洁

<xsl:template name="findGlobleString">

<xsl:param name="num"/>

<xsl:param name="step"/>

<xsl:param name="maxstep"/>


/*伪码逻辑 begin*/

if($num >= $step and $num < $maxstep)//如果num的step位上为1

{

if($step == $maxstep/2) 打印相应字符串


else if($step == $maxstep/4) 打印相应字符串

...


else if($step == 0) 输出空


if($step / 2 >0)//如果step不在最低位,继续调用自己

{

/*调用自己

传参为 1.$num-$step作为num参数传入

2.$step/2 作为step参数传入

3.$maxstep 作为maxstep参数传入

*/

}

else//step已在最低位,解析结束

{

打印空

}

}

else if($num =0 or $step =0)//解析结束标志

{

打印空

}

else if($step < $maxstep and $step>1 and $num<$maxstep)//num的$step位上数字为0,且不是最低位,$step右移一位,再次调用自己解析

{


/*调用自己

传参为 1.$num作为num参数传入

2.$step/2 作为step参数传入

3.$maxstep 作为maxstep参数传入

*/

}

else

{

打印错误信息

}


/*伪码逻辑 end*/



</xsl:template>

这样执行完这些代码之后str这个variable种存储的就是我们想要转化的字符串了。同时这个template的可扩展性也是较强的,对于位数更多的情况,直接将传入的step参数和maxstep参数做相应的修改就可以了。

上面我写的这些逻辑符都是xsl中有的,这里就不贴出源码了,要转化很容易。自己对递归也没多少认识,有更好办法的,欢迎指教!

2009-04-25


……

[阅读全文]

2009年4月10日星期五

强大的二进制数

今天实验室轮到我来发“每日一招”,(ps:解释下,这是我们项目组的一个内部活动,用来让大家在工作中将自己各方面好的经验和方法共享,同时也能活跃实验室的气氛),想了一会儿找不到什么好的东西,就将我当初在电视上看到的李开复在面试清华北大的两名计算机专业的学生时问的一个问题,如下:

有1000个苹果,现在给你十个箱子,将所有的苹果都装到箱子中,假设每个箱子都是可以装任意多的苹果的,现在要你提出一种装苹果的方案,使得要任意个苹果,都可以用其中的几个箱子搭配给出!

实验室的童鞋们果然都很聪明,很多人都在十分钟内就给出了正确的答案。同时有另外一个同学也由此引出了第二个问题:

一个奴隶主有1000坛酒,其中有1坛被人投了毒(很慢性的毒)。现在他要用他的奴隶来试毒,请问用怎么样的方法可以用尽量少的奴隶并且最少的时间把有毒的那坛找出来?

第一个问题的答案很简单,估计大部分人也能够很轻松的解决,就是让箱子装苹果的个数依次为1,2,4,8,......256, 489,大概原理就是1000个苹果用二进制表示的话是有十位,511用2进制表示是9个1,这样如果我们用前九个箱子装上2进制前九位每位数字代表的大小,我们就可以用其中的组合配出任意的一个<=511 的数了,再将最后的苹果数装入到最后的一个箱子中,如果需要的苹果数大于511而小于1000,就可以直接先将最后一个箱子的苹果给出,这样剩下来需要的苹果数就必然在511内了,这样就又可以由前面九个箱子组合配出。

第二个问题我刚开始始终不明白,只知道这题肯定与第一题极为相似,但是想了很久都不会(sigh!),最终还是请教他才得以解决。不得不承认二进制数是多么强大。题目是这样解决的:
首先呢,对1000坛酒编号,二进制号,十位即可,如“1010111010”,全部表示成十位,不足的补零。然后拿出十个奴隶,让第一个奴隶去喝把所有的编号右边第一位为0的酒喝一口,这样如果他死了说明毒酒编号的最后一位为0,否则为1;然后让第二个奴隶去将编号右边第二位为0的酒喝一口,这样就又可以确定毒酒右边第二位的数字,依次下去,就可以确定毒酒的编号了,看到没有,当我们这样分配后,可以在发现一个奴隶毒发身亡后就确定毒酒的编号了,效率够强大吧!
二进制数果真是强大!
……

[阅读全文]

两道程序员面试题

1.能否不利用额外的辅助空间,将两个int型数交换顺序?

2.现有两根不均匀的香,它们每根都能燃烧整整一个小时,现在给你两跟这样的香,你能用它确定15分钟的间隔吗?

上次跟一个同学一起去吃饭,他问了我以上两个传说中是面试题的问题,觉得很有意思!不过可惜的是这两题是在他的提示下才搞定了。

第一题相对容易一点:通过下面三步操作就可以搞定了
a = a + b;
b = a - b;
a = a - b;
但是这个我感觉是有点问题的,因为要是a,b相加正好超过了int的上限,岂不是出现数据丢失,何谈两者交换呢?

第二题有点像脑筋急转弯,我费了好大劲都想不出来,在同学提醒了我一炷香两头一起烧就能确定半个小时了,我才恍然大悟。想了一会,便给出了答案:先将一炷香两头同时点燃,这是也将另一根香的一头点燃,在第一根香烧完后,就只有确定了第二根香还能烧半个小时了,这时将它的另外一边也点燃,它就只能支持15分钟了。

两道题其实都比较简单,但是需要脑袋要灵活,善于跳出常规的思路!^_^
……

[阅读全文]

2009年3月25日星期三

做“超级毕业生”

今天中午上了一下喻信,突然看到了《超级毕业生》这篇帖子,下面还有一篇《女毕业生的死亡日记》,这两篇文章是《南方周末》上报道的,好久没上喻信,趁着中午还有点时间,就将这两篇帖子读完了,读第一篇,我几乎是张着嘴巴读完的,第二篇却几乎落泪,同样是大学生,前后的反差引起了我的深思。

可以这样说,义乌商学院的教育可以深深的打击了我们当代的这些还自以为是在重点大学的学生,“一个高职学生今年顶40个本科生,明天还会顶80个!”,这样“震撼人心”的话语让我不禁打了一个寒颤。但是他们确确实实做到了,贾少华这位副院长真的是个好院士,不管他的举措是否有些过于激进,但我们从中是可以看出他是的的确确为当代的大学生着想的,而且也确确实实取得了相当不错的效果,诚然,很多人会说,并不是每个人都适合去淘宝开店,怎么能够那么偏激的大肆鼓励学生去淘宝创业,呼吁“淘宝改变命运”呢?但是你若是不试试,你如何知道你不适合,一个根本就没有尝试过某件事的人,是根本不会真正对它有体会的,偏激一点说,像这样的人根本就没有资格去评价别人!何况这样也可以让一些人了解到自己并不适合这个方向,对自己的未来也就多了一分明确,更重要的是这样让大批的大学生能够摆脱网游的困扰,真正的将自己的青春为自己的未来去挥洒,就凭这一点就可以说明这个方法至少不是错的!

现在的大学年年扩招,重点大学的学生出去找工作照样是很难,如何真正的让大学生能够适应这个竞争日益激烈的社会,确实是一个非常严重的问题。虽然大学现在不断扩招,但是师资力量却是不敢让人恭维,一些老师上课几乎只能靠点名来保持到课率,这样难道都是我们学生贪玩,不想去上课吗?肯定是有一部分学生比较堕落,在大学这种相对自由的环境下管不住自己,但另一方面有可能是老师本身讲课质量有问题,也有可能是,课本陈旧的知识与现实严重的脱节,导致大家对这样的课产生了天然的反感,学了又如何,在考试中能取得更好的成绩?考前突击个一两周貌似就可以达到不错的效果了,那我又何必去听课呢?再者,即使考试取得了好的成绩又如何呢?可能成绩相当不错的学生,能够拿到学校的这个奖学金那个奖学金,不错不错,但是这是在学校,一天你走出了学校又会怎样呢?你还能靠你记得的那几个公式让公司聘用你吗?可能我说的比较偏激。但是我确实也是看到大学与我刚进大学时想象中的巨大反差。以前以为上了大学就可以真正学到许许多多实用的东西,十分兴奋!可是结果呢?等待我的还是计算电压电流,求电场磁场。而且每学期都会有一大堆的书学完,过了就忘了!眼睁睁的看着自己与现实社会的差距越来越远,很是痛苦!

我从来没有鄙视过读书,我也知道要真正的实践的好是需要一定的理论基础的,但是何必要在大学里面把所有的理论疯狂的往学生头上灌呢,大学不比高中,我们需要的不再是理论知识本身,我们更需要的是快速学习新知识的能力,和将知识运用于实践的能力,如何增强我们的快速学习能力,如何将知识与理论结合,三个字,多实践。在实践中,我们能够看到自己的知识的威力,能够将知识掌握的更牢固,在实践中我们也能够发现自己理论知识的不足,为了能够跟上,我们会为自己充电,这样又可以极大的提高我们的快速学习能力。当然我现在是站在一个学工的人的角度在看问题,学理的同学可能就不大一样。我想说的是并不是每个人都适合去学好这一大堆的理论,去在将来发现一个**定理,弄出一个**猜想。工与理一定要分清楚。尤其是我们现在处在这种并不发达的城市中,想要找到一个不错的实习的地方是不太容易的,相比那些像上海、北京之类的发达城市,我们首先在地理优势上就已经落后于别人,机会数目不能和他们相提并论。所以在实践环节我们要是再不加大力度,就可能永远不是别人的对手了。

贾院长说的好,杨甫当初市场营销只拿了三四十分,(人家在淘宝上开店,已经能达到月薪4万了)你能说他不懂市场营销?不仅仅是市场营销,还有好多的知识并不是你在上课能够学到的,这些就是实践得来的经验,而这些东西往往比知识本身更重要,不是你通过记住一些概念,多做两道选择题或问答题能够解决的。所以我们一定要抓住一切可以锻炼自己实践能力的机会,这才是你将来能与别人竞争的资本。

大学应该是一个能够真正因材施教的地方,这是中国的需要,也是当代大学生的需要。在大学中,做研究的要踏踏实实做研究,做工程的要认认真真做工程,这样才能让每个人都能够找到自己的兴趣点,发挥出自己的潜能。考试现在不应该成为大学生好坏的唯一衡量标准,大学里也不应该以考试来逼迫学生去学习。大学要真正让学生能够在其中学到东西,不仅仅是技术,还有现在社会急缺的各种道德品质。大学生处在青春的最旺盛期,这个时间段是及其宝贵的,希望我们都能抓住各种机会去锻炼自己,提高自己。也希望我们的大学能够通过改革日趋完善,这样才能让超级大学生能够真正的“批量生产”,这样也可以真正的让像刘伟这样的悲剧尽可能少的发生,甚至不发生!
……

[阅读全文]