20150601

当推理不需要逻辑能力,也兼 学习离散数学或数字电路有什么用处

当推理不需要逻辑能力,也兼 学习离散数学或数字电路有什么用处

1.智力测验,逻辑题,鸡兔同笼,一元二次方程

有一类智力测验题,会问到"甲说丙说的是假话,乙说甲在瞎说"什么的;还有类似这样的,"凯特是你的秘书,问是不是办公室里至少有一个人长发及腰"。得分高的,就被评为智商高,或者逻辑能力强。

这种题目所涵盖的智商 (如果能够有所涵盖的话)是非常狭窄的,不包括音乐、美术、语言等很多方面。所以,我认为这种题目啥也不代表。而且,我曾经吹过牛,说这种题目与逻辑推理能力无关。有人不信,今天我证明给你看。

我们先明确一个边界,什么能够算作智力。作为人类,区别于动物的最重要的特性是,我们会使用 (或制造,如刘典同学所强调的)工具。又,按萨特的说法,你是一个什么样的人,完全取决于你的外在,而与你内心所想无法--即,如果你终生表现得勇敢,即使每一次你都吓得心中不住地发抖,按你的表现,你仍是一个的勇敢的人。

就像函数,我们只关心它的输入与输出,或者更严格地说,我们只关心它的输入与输出间的对应关系。至于函数如何实现的,是用C语言,用电子线路,用机械,用人脑,我们并不关心。

就像中文屋子 (请GOOGLE)。

就像我拿个计算机或打开EXCEL,而你练了十年珠脑速算,我 (计算器是我的一部分) 的开方、求对数、三角函数的速度可能比你还要快。

就像你在小学是个非常聪明的学生,解鸡兔同笼问题简直不假思索,本能一样。到了初中,你还是会发现,把鸡兔同笼问题设为 二元一次方程,只有这一步需要一些思考 (需要设鸡数为x,兔数为y),然后就是机械解题了。机械解题这一步,毫无智商可言。

自从有了火器,开枪杀敌,就跟体力关系不大了。工具,是人类肢体和头脑的延伸。

幸运的是,连逻辑推理,至少智力题这种程度上的,也可以用工具解决。你,加上工具,所表现出的智商,就显得很高。

当然,有一点需要点严谨。"凯特是你的秘书,问是不是办公室里至少有一个人长发及腰",这样的题目,你需要意识到 凯特 这一命名,并不意味着秘书的性别,也不 (而不是 更不) 意味头发的长度。甚至连这点严谨,如果你能使用接下来我要说的数学工具的话,也不太需要,因为当你把凯特抽象 (形式化) 为x的时候,你不能"显然"地找到性别的依据,只好认定条件不足。

2. 两道智力题的数理逻辑解法 示范

光说理论和类比,估计你也不信。下面演示两道题目。

2.1 谁是罪犯

这道题目就是从网上随便找来的。

A 说   不是我
B 说是 D
C 说是 B
D 说   B在诬陷他
假设他们其中有一个人说的是真话,那么谁是真的罪犯?
[http://zuoye.baidu.com/question/299842b63d6092288532e871ab55857c.html]

答案是: A是罪犯
有位答题的同学说,"一个一个假设为真,其余为假.只有D说的情况可以符合."

这种题目,通常有个非常漫长的解题过程: 假设A如何,然后一顿推导;假设B如何,然后又一顿推导。

下面的方法,来自从数学家 布尔 开始的方法,据说罗素和他的学生维特根斯坦在《数学原理》或《数学的原理》中首先提出了数理逻辑的这种推导手段。现在,这种方法广泛地记载在《离散数学》和《数字电路》的数理逻辑一章中。这些前辈证明了,逻辑推导与数学计算是等价的。

为了清晰,我们分3步走。

第1步,我们做个表格,横行代表每个人所说的,纵列代表假设某个人说的是真话,交叉的单元格代表在 这一假设 (某人说的是真的)下横行对应的那个人说的话是真的还是假的。

1|       a=1 b=1 c=1 d=1
2| A !a  ?   ?   ?   ?
3| B d   ?   ?   ?   ?
4| C b   ?   ?   ?   ?
5| D !d  ?   ?   ?   ?

大写 代表发言的人,小写 代表假设 (或观点中) 此人是罪犯。如,a=1 代表(假设) a是罪犯,!a 代表 (A的观点),a不是罪犯。

其中
第2行,"! a"代表 "A 说 不是我";
第3行,"d  "代表 "B 说是 D";
第4行,"b  "代表 "C 说是 B";
第5行,"!d "代表 "D 说   B在诬陷他",即 对B的观点 (d)取非。

a=1,并非严格的表述,它的含义是,a是罪犯,并且其他三个人都不是罪犯,所以,严格的表述是: a=1 & b|c|d = 0。本文为节省空间,"并非罪犯"在表头中从略,但是"推导"中仍然需要这一条件。

第2步,我们填充表格中的单元格,设为1为真 (某人是罪犯,这一命题属实) ,0为假。

1|       a=1 b=1 c=1 d=1
2| A !a  0   1   1   1
3| B d   0   0   0   1
4| C b   0   1   0   0
5| D !d  1   1   1   0

这是这么填上的,我举一个例子,如第2行的 "a=1" 这一列。

当 a = 1 时, 这一行 "!a" 的值为 ! 1,即0。

再举个例子,第5行"b=1"这一行。

当 b = 1 (并且 a|c|d=0,也即a、c、d都为0) 时,这一行 "! d"值为 ! 0,即1,

这一步里,有时我用到了一些数理逻辑 (布尔代数,完全不是逻辑推导)的小技巧。比如"a|c|d=0,也即a、c、d都为0",这是析取 (或)的特性;下面的题目里,还对蕴含作了化简,为了计算的时候更方便。值得指出的是,即使完全不使用这些技巧,也并不不会令解题难度增加多少。甚至,你只要能查到这个表达式对应的真值表,完全不会布尔代数也能解出来。因为题量小,速度也并不慢。上面这道题,填充表格,一共解了16个单一变量的表达式,都是可以秒出结果的。

第3步,查数。

我们可以注意到,第1步是把智力题 (的众人说的话这一条件) 转换为布尔代数,第2步是在布尔代数的领域中求值,第3步,把智力题的另一条件 ("假设他们其中有一个人说的是真话")用上。此处推荐 波利亚 《怎样解题》,他老人家说,只要到了卡住的地方,把所有已知条件 (及问题)都再捋一遍。

"假设他们其中有一个人说的是真话",就是把上面填充完的表格,纵向查一下,哪一列 只有一个1,其余的都是0。上面我提到过了,1代表属实。只有"a=1"符合这一要求。

意思就是,"a=1"就是答案,即a是罪犯。

回顾。

你可能会说,我这方法求了16个表达式,而如何使用"聪明"的逻辑推理,可能表达式 (或推理过程) 根本不需要这么多个。这就跟传说中的故事一样,据说P&G的博士生想了一堆办法,才解决了盒子里到底有没有装上肥皂,而民企的农民工架上台电风扇就解决了。博士的优势在于,他的知识结构和办法*总能*解决问题,而农民工及其办法下一次就不一定好使了。

你也可能会说,我这办法也不是智力 (或能力)啊,而是知识,只要你会,人人都能解决。这正是科学技术与巫术的区别。凡是人类,都能学会;学会以后,都能应用;应用以后,人人都变聪明了。注:这种聪明,不是时下中国人太多的那种聪明。

2.1 再来一道题,谁偷吃的

A说:是B偷吃的,
B说:是D偷吃的,
C说;我没有偷吃,
D说:B在撒谎!

其中有一人说了真话,谁偷吃了蛋糕?
[http://tgyd2006.iteye.com/blog/748679]

求得的表格是这样的:

     a=1 b=1 c=1 d=1
A b  0   1   0   0
B d  0   0   0   1
C !c 1   1   0   1
D !d 1   1   1   0

注: a=1意思是 a=1 & b|c|d=0。其余三列同。

因为只有1个人说了真话,所以查数,找到只有1个1的列,即"c=1"。

结论,C偷吃了。推论,D说了真话。

作为对比,给出某位网友的推理过程:
----引文开始

假设A说的是真话那么蛋糕就是B吃的,但是C说的是假话"我没吃"就是"我吃了"所以蛋糕是C吃的,有此看来A说的是真话不成立!
假设B说的是真话那么蛋糕是D吃的,但是D说的是假话"B在说谎"就是"B没说谎",C同样说了假话"我没吃"就是"我吃了"所以B说的是真话也不成立!
假设C说的是真话那么B说的是假话"是D吃的"就是"不是D吃的",D说的假话承认了是自己吃的,因为矛盾,所以C说的真话不成立!
假设D说的是真话A,B都说的假话,所以排除B,D吃蛋糕的嫌疑,因为C说的也是
假话,就是"我吃了"所以蛋糕就是被C给吃的,而真正说真话的人是D!

----引文结束

对比自然语言的推导,你可能已经感觉到,布尔代数的方法,是不需要智力 (和逻辑推导能力) ,甚至不需要注意力,也不需要注意力持久的。

工具,正具有这样的特性,让每一个平凡人成为更强的人。

3.知识的力量

上述用布尔代数解智力题,不需要逻辑能力;不过,这种方法确实需要你 知道这种方法 的存在。

这对很多人是个障碍: 我用现在的手段,已经能 (很好地)解决这个问题了,为什么我还要学新的技术呢?我生活在田园牧歌似的岁月 (和村庄)里,不是很浪漫么。

如果在田园中,你发现了一种植物,你沾到它,甚至靠近它,在特定的月份,就会皮肤发痒。你几乎确定这种植物以前根本不存在,你几乎断定它就是你过敏的感恩,你几乎确定它就是传闻中的入侵物种--但是,你不知道它的名字。

怎么办?

根据植物的照片,GOOGLE目前还不能告诉你那是什么植物,更不能告诉你如何消除。就像有同学在网上放出照片,养的花蔫得快死了。有网友说,你都把花养成这样了,还有脸放上来呐?楼主说,就是这样了,我才想放出来请教它叫什么名字,这样,才能查一下如何照料啊。

不知道,就是无知。无知而期待解决问题,就是把前人发明过的痛苦过的,再来一次。如果想利用前人的经验,你至少需要知道,前人把它叫做什么。

你必须先具备基础知识 (领域) ,然后才能检索。你需要知道如何把叶子、花的形状用文字描述出来,还有叶子间的关系、花之间的关系。像这样:总状花序、掌状叶裂...有位同学贴过照片,问蓝色的很漂亮的花是什么。蓝色、漂亮、花,对于判断物种都没有用,我根据叶序和花序查,是百合。另一次。我们带着一盆多肉植物去同学聚会,小杨同学的爱人老赵,看了一眼就说,"景天"。景天是一个科,很多多肉都属于这一科。这就是领域知识所带来的专业技能,他甚至连查表都不需要。他接着问,"什么是多肉?"

另外的知识的力量的故事。

包师弟极其睿智,到什么程度呢。他曾经看着函数的图像,通过研究函数的周期,起伏的程度,仅根据几组给定自变量的函数的形状写出了函数的公式:

cos(α+β)-cos(α-β)

这么复杂的式子,我当时的感觉就是,你还要不要人活了。在牛人面前,大抵是这种感觉。

我能记住这个故事的一个原因是,在此时,我表现出了"知识的力量"。知识附身,智力有加成。我把包师弟的公式化简了,化简的方法,其实我们初中都学过,就是和差化积。

-2sinαsinβ

然后我就可以说,函数的公式怎么会那么复杂呢~~

知道 和差化积,拉近了我和包师弟的智商。

另一次是包师弟在解决一个问题时,使用了非常繁复的方法,实现这个方法写了一个挺长的程序,花费了不少时间。后来某一次他详细描述这个方法的时候,我突然说,"线性外插"。关同学也说,对啊,这就是线性外插。线性外插,等价于那么长的代码和解释,而且,方法更加稳妥确定,因为有数学证明。后来,我们又发现,这种问题不应该使用线性外插,而是 拟合。

知道 线性外插、拟合,拉近了我和包师弟的智商。

所有这些知识,植物分类、和差化积、线性外插、拟合,还有可以替代逻辑推理的布尔代数 (数理逻辑,用计算代替推理),作为工具武装我们,使我们成为更强的人类,因此更加自由。

所以,怎么可以说,什么什么知识,不会不知道又如何呢。不会不知道,就是无知,因此无助,因此囚禁于牢笼之中而不得自由。钥匙,前人曾经使用过有效的,就在你的面前,只要你一伸手就可以拿到,而你,打算赤手空拳伏虎屠龙吗,打算喊叫别人帮忙带你自由,打算继续忍受?

知识,就是解放我们的那把钥匙。

-------

此博客会手工同步到以下地址:

//[http://zhuanlan.zhihu.com/younggift]

[http://zhuanlan.zhihu.com/wujun]

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

20150525

抽象之艰难,一次作业分析

抽象之艰难,一次作业分析

1. 问题的提出,一次作业

要求实现 小学四则运算系统,系统出10道题,用户输入答案,系统判定对错,系统给出对错的数量。

这是以邹欣老师的《构建之法》作为教材,某高校的软件工程课程作业。

该作业要求迭代开发,在《构建之法》群里,企业的工程师、高校教师对某次某位同学提交的作业进行了点评。

这位同学提交的是 JAVA GUI 版本的程序。控制件的选择,每道题的两个数是文本框禁用,要求用户输入答案处是文本框,判断对错是文本框禁用;选择加减乘除题目,是按钮。

该同学实现了出10道题目。问题来了,邹欣老师问,如果我要求出40道题目呢?之所以有此一问,是因为该同学硬编码了10道题目的 控件和业务逻辑,她的代码看起来是这样的。

----节选代码开始

JTextField jfirst1, jfirst2, jfirst3, jfirst4, jfirst5, jfirst6,
            jfirst7, jfirst8, jfirst9, jfirst10;// 10道题的分别的第一
            个数据JLabel jsymbol1, jsymbol2, jsymbol3, jsymbol4,
            jsymbol5, jsymbol6,
            jsymbol7, jsymbol8, jsymbol9, jsymbol10;// 10道题的分别的符号
    JTextField jsecond1, jsecond2, jsecond3, jsecond4, jsecond5, jsecond6,
            jsecond7, jsecond8, jsecond9, jsecond10;// 10道题的分别的第二个数据
    JTextField janswer1, janswer2, janswer3, janswer4, janswer5, janswer6,
            janswer7, janswer8, janswer9, janswer10;// 10道题分别的结果

// 添加每道题的符号标签
        jsymbol1 = new JLabel("?");
        jsymbol2 = new JLabel("?");
        jsymbol3 = new JLabel("?");
        jsymbol4 = new JLabel("?");
...
// 设置答案对错的标签
        jjudge1 = new JLabel("?");
        jjudge2 = new JLabel("?");
        jjudge3 = new JLabel("?");
        jjudge4 = new JLabel("?");
...

/* 加法计算 */
        if (e.getSource() == AddBtn) {
            flag=1;
            jsymbol1.setText("+");
            jsymbol2.setText("+");
            jsymbol3.setText("+");
....
            fun();
            random();
        }

// 计算第二道题
            String answer2 = null;
            a2 = first2 + second2;
            answer2 = Double.toString(a2);
            String result2 = janswer2.getText();
            if (result2.equals(answer2)) {
                jjudge2.setText("对");
                true1 = true1 + 1;
                jjright.setText(Integer.toString(true1));
            } else {
                jjudge2.setText("错");
                jjresult2.setText(answer2);
            }
// 计算第三道题
// 计算第四道题

----节选代码结束


2. bad smell

该同学的全部代码在这里,java语言GUI版本的[http://www.cnblogs.com/tujiangfeng/p/4480053.html]。

事实上,能细心地安置10个控件,复制粘贴->修改其中的不同,是件很不容易的事情。需要耐心和精确,稍有不慎就会操作错误,而查找这个错误非常困难,因为它隐藏在面目相似的群体之中。又,耐心和精确,确是一种非常可贵的品质,难以替代,不过,科学和技术还给我们另一种力量,就是让 平凡的人 拥有更强大的力量。任何人都能学会,只要掌握就能更牛,这是科学与巫术的不同。

该同学的问题,在她稍晚的作业中自己回答了,"Duplicated Cod(重复代码)" [http://www.cnblogs.com/tujiangfeng/p/4500116.html],这是重要的代码坏味道,重要到,它排在了坏味道中的第一名。

所谓重复,就是看起来 它们相似。

该同学其实曾经完美的解决过这个问题,在她更早的作业中,C语言console版本的 [http://www.cnblogs.com/tujiangfeng/p/4399804.html],她用for循环实现了5道题目,判断题目对错,只写了一次代码, (而在JAVA GUI版本中,她写了10次)。

3. 解决之道

沉默的代码(某位资深工程师,他在群里不是这个名字,所以不知道是谁)在作业的博客中批阅道,"使用For循环重构上面的代码"。

那天,在群里得有10位左右资深工程师给出了相同的意见,用了各种不同而相似的说法。相信该同学已经蒙了,"他们到底说的是什么啊。"最打击人的,不少资深工程师对自己给出的方法加了限定和修饰,"这是非常基本的方法"。

如果该同学看到我这篇博客,请一定仔细读一下我下面这一段话。"基本"一词,不是指它简单,或者暗示你在道德 (勤奋、努力之类的)上 理应掌握,而是它极其经常在工业中应用,所以,需要掌握。需要掌握的原因,是这是本领域的"基本"技术,就像战士的射击。

资深工程师们的核心思想是,用循环去除重复。

该同学的疑问有二。一,她们没学过数组控件。对此,邹欣老师建议,用控制台实现,用意大概是先掌握抽象这一方法,至于控件什么的技术,倒在其次。该同学提到,JAVA没有学过控制台的程序。二,怎么循环呢,怎么抽象呢?

对于第二个疑问,即需要A.原则,B.精晰的可操作的指令,也需要C.示范。示范在后面,下面先给出指令。

把上述代码抽象为循环,A.原则是,找出代码中 相同的部分 和 有变化的部分。把相同的部分放在循环 (或者函数)中,把不同的部分,作为循环的变量 (或函数的参数。参数又译为变数,其义正对),或者作为变量的函数 (这个函数的意思是数学上的,即可以由变量求得)。

B. 指令如下:

把那些名字相似,只有最后一个数字不同的,不单独声明为变量,而是声明为数组;不用名字区分它们,而是使用数组的下标区分它们。

凡是对这些变量操作(读或写)的,改为对数组元素操作。对某元素操作的若干次,改为在循环中执行,每次变更 (比如递增1) 数组元素的下标。

一共三种代码需要关注。(1)不变的部分,在每次循环中都一样, (2)数组下标,每次循环都变更, (3)下标或循环变量可能不同,需要找到它们间的关系。本例中没有第 (3)种情况。

C. 示范,上面的代码,按资深工程师们的指示,大概改成下面这个意思。

----节选代码开始
List<JTextField> jfirst = new ArrayList<JTextField>();  // 10道题的分别的第一个数据
List<JLabel> jsymbol = new ArrayList<JLabel>();         // 10道题的分别的符号
List<JTextField> jsecond = new ArrayList<JTextField>(); // 10道题的分别的第二个数据
List<JTextField> janswer = new ArrayList<JTextField>(); // 10道题分别的结果

// 添加每道题的符号标签
// 设置答案对错的标签
int max_length = 10;
for(int i = 0; i< max_length; ++i)
{
        jsymbol.add(new JLabel("?"));
        jjudge1.add(new JLabel("?"));
}

...

/* 加法计算 */
        if (e.getSource() == AddBtn) {
            flag=1;
        for(int i = 0; i< max_length; i++)
        {
            jsymbol[i].setText("+");
            }
            fun();
            random();
        }

// 计算第二道题
// 计算第三道题
// 计算第四道题
for(int i = 0; i< max_length; ++i)
{
            String answer[i] = null;
            a[2] = first[2] + second[2];
            answer[2] = Double.toString(a[2]);
            String result[2] = janswer[2].getText();
        ....//省略的原因不是像循环的类似,而是可按上述方法修改
}
----节选代码结束



4. 不仅如此

对于教学本身的讨论,至此可以告一段落,但是更深的讨论,才刚刚开始。在经典导论教材SICP中,一共五章的书里,用了三章讲抽象,甚至标题就叫做XX抽象。可见抽象之重要。

抽象为循环、抽象为函数,以上给出的原则、指令、示范,是非常形而下的,因此更容易操作。但是,在何处情况下应该做抽象,如何抽象,是个更深刻的问题。比如,我们是否要把四则运算中的加减乘除抽象为同一个函数么,向然后向这个函数传入一个 first class 的操作符;我们是否要把供用户选择题目类型的按钮抽象为一个数组;为什么要这样做,为什么不这样做?为什么不抽象为面向对象,为什么不抽象为AOP,为什么不使用设计模式。

如果仅回答,"使用这些技术会导致代码更复杂",那么,"复杂"在这里,很大程度上只是个人的主观体验。这位同学也可以说,抽象成控件数组,还不如复制粘贴容易呢。在做项目的时候,我的学生就真的这样质疑过。当然,我们可以回答,"当代码规模更大的时候",可是,你又如何知道代码的成长方向呢?

从一次次的执行 (执行,是动态,或复制粘贴,是静态)中,发现其中不变的部分,抽象这些部分,并允许不同的部分可以在不同的情境 (第几次循环,函数的参数)下指定;还要在代码中同时包括不变和变化的部分 (比如,用循环变量和数组下标表示变化)。

这是一项异常艰难的工作。因此,教授抽象,也非常艰难,如果不是更难的话。

刘典说,他是先学会编程,后学的英语。因此,在他看来,for的第一含义就是循环,而不是"为了"。对于工程师而言,把技术内化为本能,值得称道,不过,作为教师,这就是 (如他所说)知识诅咒。因为你忘记了当初如何艰难地掌握了这一点,甚至,你并没有深刻掌握,只是每次都类比过去的成功经验,照样应用了而已。

为什么艰难?因为在编程以外的经验中,我们鲜能发现 循环。有人可能会说,日出而作、日落而怎,每个学期、每周的课表,这不是循环吗?这不是。这不是实现完整的循环所需要的,是粗糙的。在刚刚提到的这些循环中,什么是循环变量,循环的开始和终止条件是什么,有必要存在循环变量吗,是否可以用迭代器取代,用foreach呢,在循环体中,哪些是每次循环要改变的,哪些是不变的。

有人说,这简单啊,上述问题都能答上来。但是,你在日常生活中考虑上述循环的时候,会考虑这些问题吗,还是只是粗糙地应付过去?这就是日常生活中没有循环这一经验的原则。

而在掌握一项技能之初,有类似的经验非常重要。这就是为什么物理学的力学部分,男同学普遍比女同学掌握快的原因--经验。这也是为什么物理学的电学部分,好多同学一下子就蒙了的原因,不是因为看不见摸不着,而是现实中没有这样的东西。水流、水压,这些比喻并不与电学概念完全对应,更何况大家对这些流体 (静?) 力学的经验也就呵呵。

循环的经验来自于哪里,为什么循环对很多人难以掌握?

与循环高度类似的,是高中代数中的数学归纳法,是数列的通项,是求得的sigma上面的那个i。而这些,有很多人本来学得就烂。这就是循环的抽象。当然,前面学得不好,也可以利用计算机的for循环学习这种抽象。

(题外话,类似的,与实验技能相关的,实验现象说明什么,假阴性假阳性,这些对应的是初中平面几体里的充分条件必要条件。很多人没有把逻辑推理内化,或者没有自觉地使用这一工具,因此在做实验的时候会糊涂。)

为什么抽象,如何抽象,这个话题也可以延伸到面向对象的继承和多态,不赘述。我想说的是,抽象,并不是简单和自然的,不是理应掌握的技能,而是必须掌握的技能。

-------

博客会手工同步到以下地址:

[http://zhuanlan.zhihu.com/younggift]

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

20150107

Fwd: 百度地图坐标偏移的纠正

>
> 百度地图坐标偏移的纠正
>
> 1. 问题
>
> 在使用百度地图开发时,输入经纬度 (用google earth或GPS设备得到) ,会发现坐标显示位置偏移。
>
> 比如,已知东北师范大学经纬度 125.3249352, 43.8593245。经纬度可以通过地理科学学院门口的雕塑上查到,可以通过google earth查到,可以通过能显示经纬度的GPS设备,或者用iphone在东北师大拍张照片,然后用带有识别exif的工具比如 google picasa查到。
>
> 在下述代码1中,我们发现,标记 125.3249352, 43.8593245 的位置不在东北师大,而是偏移到了南湖里。
>
> -----代码1开始--------
>
> <html>
> <head>
> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
> <style type="text/css">
> body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;}
> #l-map{height:100%;width:78%;float:left;border-right:2px solid #bcbcbc;}
> #r-result{height:100%;width:20%;float:left;}
> </style>
> <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.4"></script>
> <title>baidu map demo</title>
> </head>
> <body>
> <div id="allmap"></div>
> </body>
> </html>
> <script type="text/javascript">
> var map = new BMap.Map("allmap"); // 创建Map实例
> var point = new BMap.Point(125.3249352, 43.8593245); // 创建点坐标
>
> var marker = new BMap.Marker (point);
> marker.setTitle ("This is a Marker.");
> map.addOverlay (marker);
>
> map.centerAndZoom(point,15); // 初始化地图,设置中心点坐标和地图级别。
> map.enableScrollWheelZoom(); //启用滚轮放大缩小
>
> map.addEventListener('click', function(e){
> console.log(e.point);
> });
> </script>
>
>
> -----代码1结束--------
>
> 对于坐标偏移,百度的官方解释是 国家要求 + 百度的二次加密。百度支持把其
> 他坐标 (google的, gps设备的)转换为百度地图的坐标,这样显示在百度地图上
> 的标记位置就不偏移了。
>
> 2. 解决
>
> 使用下述代码,在百度地图上,标记点的位置是正确的。
>
> 下述代码抄自网络并修改,最初来源已不可考。谢谢原作者。
>
> 代码2在代码1的基础上做了修改,调用了百度的API[http://api.map.baidu.com/api?v=1.4],及[convertor.js]即代码3。
>
> 用到了 javascript的闭包和回调。
>
> ------代码2开始------
>
> <html>
> <head>
> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
> <style type="text/css">
> body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;}
> #l-map{height:100%;width:78%;float:left;border-right:2px solid #bcbcbc;}
> #r-result{height:100%;width:20%;float:left;}
> </style>
> <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.4"></script>
> <script type="text/javascript" src="convertor.js"></script>
> <title>baidu map demo</title>
> </head>
> <body>
> <div id="allmap"></div>
> </body>
> </html>
>
> <script type="text/javascript">
>
> var map = new BMap.Map("allmap"); // 创建Map实例
>
>
> var point = new BMap.Point(125.3249352, 43.8593245); // 创建点坐标
> BMap.Convertor.translate(point, 0, function(point){
>
> var marker = new BMap.Marker (point);
> marker.setTitle ("This is a marker");
> map.addOverlay (marker);
>
> map.centerAndZoom(point,15); // 初始化地图,设置中心点坐标和地图级别。
> map.enableScrollWheelZoom(); //启用滚轮放大缩小
>
> map.addEventListener('click', function(e){
> console.log(e.point);})
>
> });
> ;
> </script>
>
>
> ------代码2结束------
>
> ------代码3开始------
>
> //2011-7-25
> (function(){ //闭包
> function load_script(xyUrl, callback){
> var head = document.getElementsByTagName('head')[0];
> var script = document.createElement('script');
> script.type = 'text/javascript';
> script.src = xyUrl;
> //借鉴了jQuery的script跨域方法
> script.onload = script.onreadystatechange = function(){
> if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){
> callback && callback();
> // Handle memory leak in IE
> script.onload = script.onreadystatechange = null;
> if ( head && script.parentNode ) {
> head.removeChild( script );
> }
> }
> };
> // Use insertBefore instead of appendChild to circumvent an IE6 bug.
> head.insertBefore( script, head.firstChild );
> }
> function translate(point,type,callback){
> var callbackName = 'cbk_' + Math.round(Math.random() * 10000); //随机函数名
> var xyUrl = "http://api.map.baidu.com/ag/coord/convert?from="+ type + "&to=4&x=" + point.lng + "&y=" + point.lat + "&callback=BMap.Convertor." + callbackName;
> //动态创建script标签
> load_script(xyUrl);
> BMap.Convertor[callbackName] = function(xyResult){
> delete BMap.Convertor[callbackName]; //调用完需要删除改函数
> var point = new BMap.Point(xyResult.x, xyResult.y);
> callback && callback(point);
> }
> }
>
> window.BMap = window.BMap || {};
> BMap.Convertor = {};
> BMap.Convertor.translate = translate;
> })();
>
>
> ------代码3结束------
>
> 4. 完整代码在[http://download.csdn.net/detail/younggift/8334749]。
>
> 参考:
> 1. [http://www.cnblogs.com/funnydavid/archive/2011/03/02/1969244.html]
>
> 2. 百度的解释
> [http://developer.baidu.com/map/question.htm]
> 百度坐标为何有偏移?
>
> 国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。百度坐标在此基础上,进行了BD-09二次加密措施,更加保护了个人隐私。百度对外接口的坐标系并不是GPS采集的真实经纬度,需要通过坐标转换接口进行转换。
>
> 如何从其他体系的坐标迁移到百度坐标?
>
> 开发者可以使用坐标转换接口进行转换。JavaScript API 、Android SDK、iOS SDK的开发用户可直接调用相应方法进行转换。
>
> 3. 百度的手册
> [http://developer.baidu.com/map/changeposition.htm]
>
> ------------------------------------------------------------
>
> 博客会手工同步到以下地址:
>
> [http://giftdotyoung.blogspot.com]
>
> [http://blog.csdn.net/younggift]
>

20150103

Fwd: 网页内联图片 html inline image


网页内联图片 html inline image

不是像这样,
<img src="http://www.nenu.edu.cn/xiaohui.png">

上述代码中,图片是独立于HTML而存在于另一个URL的。

内联是像下面这样,图片是HTML的一部分,这样适合用代码生成,或者javascript改写。
把下面的代码保存为 html 文档,用浏览器打开,可见效果。

参考:

[http://stackoverflow.com/questions/1207190/embedding-base64-images]

[http://www.bigfastblog.com/embed-base64-encoded-images-inline-in-html]

[http://base64image.org/]


-----代码开始-------------

<img alt="Embedded Image" src="data:image/png;base64,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" />

-----代码开始-------------

------------------------------------------------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

网页内联图片 html inline image

不是像这样,
<img src="http://www.nenu.edu.cn/xiaohui.png">

上述代码中,图片是独立于HTML而存在于另一个URL的。

内联是像下面这样,图片是HTML的一部分,这样适合用代码生成,或者javascript改写。
把下面的代码保存为 html 文档,用浏览器打开,可见效果。

参考:

[http://stackoverflow.com/questions/1207190/embedding-base64-images]

[http://www.bigfastblog.com/embed-base64-encoded-images-inline-in-html]

[http://base64image.org/]


-----代码开始-------------

<img alt="Embedded Image" src="data:image/png;base64,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" />

-----代码开始-------------

------------------------------------------------------------

博客会手工同步到以下地址:

[http://giftdotyoung.blogspot.com]

[http://blog.csdn.net/younggift]

发自我的 iPhone
发自我的 iPhone