小编cha*_*der的帖子

如何以允许快速插入任何索引的方式表示一系列音乐笔记?

为了"有趣",并学习函数式编程,我正在使用Clojure开发一个程序,该程序使用来自这种音乐理论的思想称为"Westergaardian Theory"进行算法组合.它产生一系列音乐(其中一行只是一个由一系列音符组成的音符,每个音符都有音高和持续时间).它基本上是这样的:

  1. 从包含三个音符的行开始(选择这些音符的具体细节并不重要).
  2. 随机执行此行中的几个"操作"之一.该操作从满足特定标准的所有相邻音符对中随机选取(对于每对,标准仅取决于该对并且独立于该行中的其他音符).它在所选对之间插入一个或多个音符(取决于操作).每个操作都有自己独特的标准.
  3. 继续在线上随机执行这些操作,直到该线为所需长度.

我遇到的问题是我的实现速度非常慢,我怀疑它可以更快.我是Clojure和函数式编程的新手(虽然我对OO很有经验),所以我希望有更多经验的人可以指出我是不是在考虑功能范例还是错过了一些FP技术.

我目前的实现是每一行都是一个包含地图的矢量.每张地图都有:note和a:dur.:note的值是表示音符的关键字,如:A4或:C#3.:dur的值是一个分数,表示音符的持续时间(1是整个音符,1/4是四分音符等等).因此,例如,表示从C3开始的C大调比例的线条如下所示:

[
{:note :C3 :dur 1}
{:note :D3 :dur 1}
{:note :E3 :dur 1}
{:note :F3 :dur 1}
{:note :G3 :dur 1}
{:note :A4 :dur 1}
{:note :B4 :dur 1}
]
Run Code Online (Sandbox Code Playgroud)

这是一个有问题的表示,因为实际上没有一种快速的方法可以插入到向量的任意索引中.但插入是这些线路上最常执行的操作.我当前用于将音符插入一行的可怕功能基本上在插入点使用子集分割矢量,使用conj连接第一部分+音符+最后部分,然后使用flatten和vec使它们全部在一维中向量.例如,如果我想将C3和D3插入索引3处的C大调(F3所在的位置),它会这样做(我将使用音符名称代替:note和:dur map):

  1. (conj [C3 D3 E3] [C3 D3] [F3 G3 A4 B4]),创建[C3 D3 E3 [C3 D3] [F3 G3 A4 B4]]
  2. (vec(flatten previous-vector))给出[C3 D3 E3 C3 D3 F3 G3 A4 B4]

运行时间是O(n),AFAIK.

我正在寻找一种方法来加快插入速度.我已经搜索了有关Clojure数据结构的信息,这些数据结构有快速插入但没有找到任何可行的方法.我找到了"手指树",但它们只允许在列表的开头或结尾快速插入.

编辑:我把它分成两个问题.另一部分在这里.

algorithm functional-programming clojure data-structures

6
推荐指数
1
解决办法
219
查看次数

使用函数在Clojure中生成docstring

我希望能够以编程方式为clojure中的某个函数编写docstring.

例如,我希望能够做到这样的事情:

(defn my-function
    (str "Here are some numbers " (range 10))
    []
    (println "This function does nothing right now."))
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试这样做时,我得到"参数decleration str应该是一个向量".这在clojure中是不可能的,还是有一些偷偷摸摸的方式来做到这一点?以编程方式生成文档字符串的部分对我来说很有用.

clojure

2
推荐指数
1
解决办法
95
查看次数