📜  排序 |自然语言编程

📅  最后修改于: 2021-10-22 02:57:36             🧑  作者: Mango

Osmosian Plain English 唯一的复合数据类型是记录和双向链表。当我们需要对列表进行排序时,我们会使用我将在下面描述的简单递归归并排序。但首先我们需要一些东西来排序。让我们对水果进行排序,让我们从类型定义开始:

A fruit is a thing with a name.

当“事物”一词出现在类型定义中时,我们的编译器会在幕后施展一点魔法,使事物(双关语)更加强大和灵活。例如,上面的定义实际上会导致定义以下数据类型:

所以一个 Fruit 实际上就是一个包含 Fruit 记录地址的指针。

并且每个 16 字节的水果记录都有一个隐藏的 8 字节前缀,带有两个用于将这些记录链接到列表的指针,以及水果的名称,它是一个字符串。纯英文字符串存储在堆中,可以是任意长度。所以 Fruit Record 中的 Name 实际上只是两个指针,分别指向 Heap 上字符串的第一个和最后一个字节。字符串内存是自动管理的,但事物内存是由程序员管理的。

编译器生成的第三种类型用作水果记录列表的锚点。这样的列表被简单地(并且直观地)称为 Fruits,即 Fruit 的复数形式。

现在让我们以随机顺序将一些水果添加到列表中,并对它们进行排序。以下是我们测试程序中的顶级语句:

To run:
Start up.
Create some fruits.
Write the fruits on the console.
Skip a line on the console.
Sort the fruits.
Write the fruits on the console.
Destroy the fruits.
Wait for the escape key.
Shut down.

以下是将被称为“创造一些水果”的例程:

To create some fruits:
Add "banana" to the fruits.
Add "apple" to the fruits.
Add "orange" to the fruits.
Add "bacon" to the fruits.
Add "pineapple" to the fruits.
Add "pomegranate" to the fruits.
Add "tomato" to the fruits.
Add "grape" to the fruits.
Add "fig" to the fruits.
Add "date" to the fruits.

To add a name to some fruits:
Allocate memory for a fruit.
Put the name into the fruit's name.
Append the fruit to the fruits.

现在我们准备好排序了。这是排序例程:

To sort some fruits:
If the fruits' first is the fruits' last, exit.
Split the fruits into some left fruits and some right fruits.
Sort the left fruits.
Sort the right fruits.
Loop.
Put the left fruits' first into a left fruit.
Put the right fruits' first into a right fruit.
If the left fruit is nil, append the right fruits to the fruits; exit.
If the right fruit is nil, append the left fruits to the fruits; exit.
If the left fruit's name is greater than the right fruit's name,
  move the right fruit from the right fruits to the fruits; repeat.
Move the left fruit from the left fruits to the fruits.
Repeat.

当我们运行这个程序时,控制台上的输出是这样的:

但是速度快吗?让我们看看使用这个修改后的测试程序:

To run:
Start up.
Write "Working..." on the console.
Put 10000 into a count.
Create some fruits using "apple" and the count.
Start a timer. Sort the fruits. Stop the timer.
Write the timer then " milliseconds for " then the count on the console.
Destroy the fruits.
Put 100000 into the count.
Create the fruits using "apple" and the count.
Start the timer. Sort the fruits. Stop the timer.
Write the timer then " milliseconds for " then the count on the console.
Destroy the fruits.
Put 1000000 into the count.
Create the fruits using "apple" and the count.
Start the timer. Sort the fruits. Stop the timer.
Write the timer then " milliseconds for " then the count on the console.
Destroy the fruits.
Wait for the escape key.
Shut down.

这次的果实,一开始是这样的:

apple 0010000
apple 0009999
apple 0009998
...

控制台上的输出如下所示:

我承认不是很线性。但也不是指数级的糟糕。十倍的记录需要大约十倍的时间来排序。有一种使用大“O”、小“n”和“日志”之类的技术表达方式,但普通英语程序员通常不这么认为。而且它很稳定,正如普通英语程序员所期望的那样——具有重复排序值的记录保留其原始序列。

好,简单,有用的东西。