惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - linkcd

linkcd胡扯职业生涯规划(二): 关于 人 linkcd胡扯职业生涯规划(一): 关于定位 如何才能用好Email? 让Switch-Case/If-Else-If-Else从你系统中走开 [翻译]每个作者都应该懂的统计学 Part I Castle.MircoKernel Class Diagram - Part I 一个不错的scheme入门PPT 人格类型 测试结果 .Net 2.0 下Data Container性能比较: Binary Serialize Dataset vs Custom Classes 智能替换DataTable.Select中会导致错误的单引号 - linkcd - 博客园 Nullable Type is an immutable type Why does Dataset NOT serialize its BinaryFormat property? (ADO.net 2.0) Undocumented Keywords in C# System.Int32&是个啥? 回FantasySoft 4个程序员的一天 n久以前写的火星文 Solution for SICP 在Vs.net中集成 NDoc生成的 Html Help 2帮助文档
《4个程序员的一天》(续) 由idior的问题想到的
linkcd · 2005-07-21 · via 博客园 - linkcd

《4个程序员的一天》一文中,idior问道:

不知道类似foo(+,-,+,*,/, a) //a is a array
实现a[0]+a[1]+a[2]*a[3]/a[4]这种功能能实现吗?(用FP)

昨晚去看了看scheme的数据结构操作,得出以下解法:(;号后面是注释)
(define (inner-runner 1st-number operators numbers)
  (if (= 0 (length operators))
    1st-number
    (inner-runner ((car operators) 1st-number (car numbers))   ; calculate new 1st-number
                          (cdr operators)                                            ; get new operators list
                          (cdr numbers))))                                          ; get new numbers list

(define (Foo operators numbers)
  (inner-runner (car opes) ops (cdr opes)))

然后我们来run run试试:3 * 5 - 2 + 4  = 17
> (Foo (list * - + ) (list 3 5 2 4))
等于17 ,得解 ;)

好了,现在来说下解题的思路:
Setp1:从Numbers中“POP”出第一个数作为初始化操作数,叫做1st-number,。Numbers现在剩下n个数字,我们称这个新的list为Numbers*.

Setp2:然后递归的分别从Operators和Numbers*里“POP”出运算符和第二个运算数,拿来和前面我们拿到的1st- number做运算,把得到的结果当作新的1st-number,连同新的Operators和新的Numbers*,重复step2,直到 Operators变为空。

这时候再回过头来看上面的scheme代码:

先简单说明下scheme的语法:
(list * - + ) :构造一个list,包含3个元素:*,-, +
(length operators):得到operators这个list的长度

(car operators):得到operators这个list的第一个元素。
例:(car (list 1 2 3)) = 1,注意它返回的是一个元素,不是list

(cdr operators):得到operators这个list从第二个元素开始的子list
例:(cdr (list 1 2 3)) = (list 2 3),注意它返回的是个子list而不是元素

来看看inner-runner函数,它完成的是step2的工作:
它先看看operators是否为空,如果为空就直接返回1st- number;如果不是,那么分别取得一个operator和一个number,进行(operator 1st-number number)运算,把得到的结果又当作1st-number,连同剩下的operators和numbers进行下一轮的递归。

至于主函数foo就比较简单了。它接受2个list类型的参数:Operators,包含n个运算符,Numbers,包含n+1个数字(当然你也 可以放多于n+1的数字,不过多的数不会参与运算),Foo做的工作只是取出最初的1st-number,剩下的就交给inner-runner搞定了。


至于预算步骤,让我们来看看(先减少些运算符以缩小运算过程):
(Foo (list * - ) (list 3 5 2))  =>

(inner-runner
  (car (list 3 5 2))
  (list * -)
  (cdr (list 3 5 2))) =>

(inner-runner
  ((car (list * -))
   3
   (car (list 5 2)))
  (cdr (list * -))
  (cdr (list 5 2))) =>

(if (=
     0
     (length (list -)))
  15
  (inner-runner
    ((car (list -))
     15
     (car (list 2)))
    (cdr (list -))
    (cdr (list 2)))) => 等于13

怎么样,明白了吧? 事实上,scheme很多运算都是靠这种简单的递归来完成的。

如idior所说,这个问题可以在".net下利用delegate的多播可以方便实现, java利用compostion模式也能完成"。(如果idior你有时间的话,能否说明一下compostion的解法呢? 毕竟Design Pattern方面你比较熟,呵呵)

而且就表现方面来说,虽然scheme代码看上去比较少,不过对于大多数programmer来说,代码的可读性也是非常重要的。FP的代码咋看上去,的确很让人头晕...@_@

写到这里,我们的Semon同志过来看了看我这post的草稿,对我上面最后一句话很是不屑,然后提了一个问题:

既然已知3 * 5 - 2 + 4  = 17,那么用scheme这样写:(Foo (list * - + =) (list 3 5 2 4 17)),即在operators最后加入一个=号,在numbers最后加入结果17,该语句返回true。(Foo (list * - + =) (list 3 5 2 4 18)) 返回false。

你能用java或C#实现这个最后判等的功能么?

哇呀,这可把我难倒了...

各位看官,您有啥好建议么?