现在我总是听说二进制搜索树比随机选择的数据更快地构建,而不是有序数据,因为有序数据需要显式重新平衡以保持树高最小.
最近我实现了一个不可变的treap,一种特殊的二叉搜索树,它使用随机化来保持自己相对平衡.与我的预期相反,我发现我可以持续建立一个快速约2倍的treap,并且通常比有序数据更好地平衡 - 而且我不知道为什么.
这是我的treap实现:
这是一个测试程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static Random rnd = new Random();
const int ITERATION_COUNT = 20;
static void Main(string[] args)
{
List<double> rndTimes = new List<double>();
List<double> orderedTimes = new List<double>();
rndTimes.Add(TimeIt(50, RandomInsert));
rndTimes.Add(TimeIt(100, RandomInsert));
rndTimes.Add(TimeIt(200, RandomInsert));
rndTimes.Add(TimeIt(400, RandomInsert));
rndTimes.Add(TimeIt(800, RandomInsert));
rndTimes.Add(TimeIt(1000, RandomInsert));
rndTimes.Add(TimeIt(2000, RandomInsert));
rndTimes.Add(TimeIt(4000, RandomInsert));
rndTimes.Add(TimeIt(8000, RandomInsert));
rndTimes.Add(TimeIt(16000, RandomInsert));
rndTimes.Add(TimeIt(32000, RandomInsert));
rndTimes.Add(TimeIt(64000, RandomInsert));
rndTimes.Add(TimeIt(128000, RandomInsert));
string rndTimesAsString = string.Join("\n", rndTimes.Select(x …Run Code Online (Sandbox Code Playgroud) 我读了很多次
从F#或任何其他.NET语言生成的程序集(几乎)难以区分.
然后我在.NET 4(beta 2)上试验F#和C#interop.我用以下类创建了一个新的解决方案和一个C#项目:
public class MyClass {
public static int Add(int a, int b) { return a + b; }
}
Run Code Online (Sandbox Code Playgroud)
然后,在F#项目上,在引用C#项目之后,我尝试了:
MyClsas.Add(4, 5) |> printfn "%d" // prints 9 (no kidding!)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.然后又出现了我多次读过的另一句话(也许在不同的书上):
将参数传递给其他.NET库中的函数时,使用类似".MethodName(parm1,parm2)"的语法,即参数作为元组传递.
将其添加到我曾经在SO上阅读的内容(但是无法找到它链接到的),在OP试图创建使用的问题[ 4, 5, 6 ](当他的意思[4; 5; 6])时:
"逗号是'元组创建运算符',因为其他一切都使用了分号."
然后我将我的课修改为以下内容:
public class MyClass {
public static int Add(int a, int b) { return a + b; }
public static int Add(Tuple<int, int> a) { return a.Item1; }
}
Run Code Online (Sandbox Code Playgroud)
现在我尝试在F#上使用它:
MyClass.Add(4, 5) …Run Code Online (Sandbox Code Playgroud) 我在C#中编写不可变二进制树的不同实现,我希望我的树从基类继承一些常用方法.
不幸的是,它从基类派生类是一败涂地缓慢.非派生类可以充分发挥作用.以下是两个几乎相同的AVL树实现,用于演示:
这两棵树具有完全相同的代码,但我在基类中移动了DerivedAvlTree.Insert方法.这是一个测试应用程序:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Juliet.Collections.Immutable;
namespace ConsoleApplication1
{
class Program
{
const int VALUE_COUNT = 5000;
static void Main(string[] args)
{
var avlTreeTimes = TimeIt(TestAvlTree);
var derivedAvlTreeTimes = TimeIt(TestDerivedAvlTree);
Console.WriteLine("avlTreeTimes: {0}, derivedAvlTreeTimes: {1}", avlTreeTimes, derivedAvlTreeTimes);
}
static double TimeIt(Func<int, int> f)
{
var seeds = new int[] { 314159265, 271828183, 231406926, 141421356, 161803399, 266514414, 15485867, 122949829, 198491329, 42 };
var …Run Code Online (Sandbox Code Playgroud) 我在第379页的Expert F#副本中注意到以下注释:
传递和处理消息
通常在共享内存并发和消息传递并发之间进行区分 .前者在本地计算机上通常更有效,本章后面的"使用共享内存并发"一节中对此进行了介绍.后者扩展到没有共享内存的系统,例如分布式系统,也可用于避免与共享内存相关的性能问题.
我感兴趣的是消息在没有共享内存的进程之间传递并发.Expert F#和互联网上演示如何使用MailboxProcessor的所有示例都包含此代码的一些变体:
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop n =
async {
do printfn "n = %d, waiting... " n
let! msg = inbox.Receive()
match msg with
| -1 ->
do printfn "'Til the bitter end..."
return ()
| n -> return! loop(n + msg)
}
loop 0)
counter.Post(20)
counter.Post(50)
counter.Post(-1) // kill mailbox
Run Code Online (Sandbox Code Playgroud)
换句话说,在将消息发布到其通道之前,必须在共享内存中拥有邮箱处理器的句柄.据我所知,这不是Erlang风格的并发,因为您只能在同一进程中将消息发布到MailboxProcessors(注意:进程,而不是线程).
一个进程中的一个MailboxProcessor是否可以将消息发送到另一个MailboxProcessor进程?如果是这样,你能提供样品吗?
所以我的公司使用Castle Windsor IoC容器,但感觉"关闭":
设计系统的人坚持认为IoC容器使系统更好.我们有1200多个公共类,所以它是一个很大的系统,你期望找到像Windsor这样的框架.但我仍然持怀疑态度.
我的公司是否有效地使用IoC?使用Windsor的新对象比使用new关键字的新对象更有优势吗?
我正在开展一个大型项目,即使有1000次自动测试和100%代码覆盖率,我们也会得到一些荒谬的错误.我们得到的大约95%的错误是NullReferenceExceptions.
有没有办法在编译时强制执行空值检查?
除此之外,有没有办法在单元测试中自动执行空值检查而不必自己编写空案例的测试?
我希望我没有错过任何明显的东西,但我一直在玩F#表达式,我想动态评估引用的表达式.例如,我想写这样的东西:
let x = <@ 2 * 5 @>
let y = transform x // replaces op_Multiply with op_Addition, or <@ 2 + 5 @>
let z = eval y // dynamically evaluates y, returns 7
Run Code Online (Sandbox Code Playgroud)
是否有内置的F#方法可以评估引用的表达式,还是我必须自己编写?
作为一个纯粹的学术练习,我从头开始编写一个递归下降解析器 - 不使用ANTLR或lex/yacc.
我正在写一个简单的函数,它将数学表达式转换为它们的等效AST.我有以下内容:
// grammar
type expr =
| Lit of float
| Add of expr * expr
| Mul of expr * expr
| Div of expr * expr
| Sub of expr * expr
// tokens
type tokens =
| Num of float
| LParen | RParen
| XPlus | XStar | XMinus | XSlash
let tokenize (input : string) =
Regex.Matches(input.Replace(" ", ""), "\d+|[+/*\-()]")
|> Seq.cast<Match>
|> Seq.map (fun x -> x.Value)
|> Seq.map (function
| …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个程序来以编程方式确定任意图像中的旋转角度或旋转角度.
图像具有以下属性:
到目前为止,我已经提出了这个策略:从左到右画一条路线,总是选择最近的白色像素.据推测,从左到右的路线将优选沿着图像倾斜的文本行之间的路径.
这是我的代码:
private bool IsWhite(Color c) { return c.GetBrightness() >= 0.5 || c == Color.Transparent; }
private bool IsBlack(Color c) { return !IsWhite(c); }
private double ToDegrees(decimal slope) { return (180.0 / Math.PI) * Math.Atan(Convert.ToDouble(slope)); }
private void GetSkew(Bitmap image, out double minSkew, out double maxSkew)
{
decimal minSlope = 0.0M;
decimal maxSlope = 0.0M;
for (int start_y = 0; start_y < image.Height; start_y++)
{
int end_y = start_y;
for (int x …Run Code Online (Sandbox Code Playgroud) 我刚刚注意到F#允许我使用带有文字和其他模式的let绑定,如下所示:
let fib 0 = 1
let exists item [] = false
let car (hd :: tl) = hd
let cdr (hd :: tl) = tl
Run Code Online (Sandbox Code Playgroud)
F#正确地将这些函数解释为一种模式匹配,因为我给出了以下警告:
警告1此表达式的不完整模式匹配.例如,值"1"将不匹配
警告2此表达式的不完整模式匹配.例如,值"[_]"将不匹配
等等
这些函数按预期工作,但我想用这种样式定义一个具有完全模式匹配的函数,但是我在F#手册中找不到关于这种替代模式匹配语法的任何信息.
我知道我可以使用let whatever = function ...并let whatever x = match x with ...获得我想要的结果,但我刚刚发现了另一种模式匹配的语法,如果我不知道如何使用它,它会永远唠叨我.
如何使用上面显示的替代模式匹配语法编写函数?
c# ×5
f# ×5
performance ×2
concurrency ×1
erlang ×1
inheritance ×1
null ×1
parameters ×1
parsing ×1
quotations ×1
syntax ×1
treap ×1
tuples ×1