Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在受限特征语言中对并行数组排序的最有效方法_Algorithm_Sorting_Scripting - Fatal编程技术网

Algorithm 在受限特征语言中对并行数组排序的最有效方法

Algorithm 在受限特征语言中对并行数组排序的最有效方法,algorithm,sorting,scripting,Algorithm,Sorting,Scripting,环境:我使用的是一种专有的脚本语言,其中没有用户定义的函数。我可以创建和使用各种循环和基本类型的局部变量 我有两个相关的数组,“时间”和“值”。它们都包含浮点值。我想对“times”数组进行数字排序,但必须确保对“values”数组应用相同的操作。没有递归之类的好处,我能做的最有效的方法是什么?只需使用您最喜欢的排序算法(例如快速排序或合并排序)并使用它对“值”数组进行排序。每当在“值”中交换两个值时,也要在“时间”数组中交换具有相同索引的值 因此,基本上您可以采用任何快速排序算法并修改swap

环境:我使用的是一种专有的脚本语言,其中没有用户定义的函数。我可以创建和使用各种循环和基本类型的局部变量


我有两个相关的数组,“时间”和“值”。它们都包含浮点值。我想对“times”数组进行数字排序,但必须确保对“values”数组应用相同的操作。没有递归之类的好处,我能做的最有效的方法是什么?

只需使用您最喜欢的排序算法(例如快速排序或合并排序)并使用它对“值”数组进行排序。每当在“值”中交换两个值时,也要在“时间”数组中交换具有相同索引的值

因此,基本上您可以采用任何快速排序算法并修改swap()操作,以便交换两个数组中的元素。

请看下面的示例。这是执行合并排序的非递归方式。这里介绍的版本使用函数调用,但是可以很容易地内联

就像martinus说的,每次在一个数组中更改一个值时,在并行数组中执行完全相同的操作

这是一个稳定的非递归mergesort的类似C的版本,它不进行函数调用,也不使用递归

const int arrayLength = 40;
float times_array[arrayLength];
float values_array[arrayLength];

// Fill the two arrays....

// Allocate two buffers
float times_buffer[arrayLength];
float values_buffer[arrayLength];
int blockSize = 1;

while (blockSize <= arrayLength)
{
    int i = 0;
    while (i < arrayLength-blockSize)
    {
        int begin1 = i;
        int end1 = begin1 + blockSize;
        int begin2 = end1;
        int end2 = begin2 + blockSize;

        int bufferIndex = begin1;
        while (begin1 < end1 && begin2 < end2)
        {
            if ( values_array[begin1] > times_array[begin2] )
            {
                times_buffer[bufferIndex] = times_array[begin2];
                values_buffer[bufferIndex++] = values_array[begin2++];
            }
            else
            {
                times_buffer[bufferIndex] = times_array[begin1];
                values_buffer[bufferIndex++] = values_array[begin1++];
            }
        }
        while ( begin1 < end1 )
        {
            times_buffer[bufferIndex] = times_array[begin1];
            values_buffer[bufferIndex++] = values_array[begin1++];
        }
        while ( begin2 < end2 )
        {
            times_buffer[bufferIndex] = times_array[begin2];
            values_buffer[bufferIndex++] = values_array[begin2++];
        }

        for (int k = i; k < i + 2 * blockSize; ++k)
        {
            times_array[k] = times_buffer[k];
            values_array[k] = values_buffer[k];
        }

        i += 2 * blockSize;
    }
    blockSize *= 2;
}
const int arraylelength=40;
浮点时间_数组[arrayLength];
浮点值_数组[arrayLength];
//填充两个数组。。。。
//分配两个缓冲区
浮动时间_缓冲区[排列长度];
浮点值_缓冲区[arrayLength];
int blockSize=1;
while(块大小乘以数组[begin2])
{
times_buffer[bufferIndex]=times_数组[begin2];
值\缓冲区[bufferIndex++]=值\数组[begin2++];
}
其他的
{
times_buffer[bufferIndex]=times_数组[begin1];
值\缓冲区[bufferIndex++]=值\数组[begin1++];
}
}
while(begin1
您可以维护索引表并对索引表进行排序。

这样你就不必担心时间和价值观的一致性

无论何时需要排序值,都可以在排序索引上查找

如果将来您决定有第三个值,排序代码将不需要任何更改

下面是C#中的一个示例,但适应您的脚本语言应该不难:

static void Main() {

    var r = new Random();

    // initialize random data
    var index = new int[10];      // the index table
    var times = new double[10];   // times 
    var values = new double[10];  // values

    for (int i = 0; i < 10; i++) {
        index[i] = i;
        times[i] = r.NextDouble();
        values[i] = r.NextDouble();
    }

    // a naive bubble sort
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 10; j++)

            // compare time value at current index
            if (times[index[i]] < times[index[j]]) {

                // swap index value (times and values remain unchanged)
                var temp = index[i];
                index[i] = index[j];
                index[j] = temp;
            }

    // check if the result is correct
    for (int i = 0; i < 10; i++)
        Console.WriteLine(times[index[i]]);

    Console.ReadKey();

}
static void Main(){
var r=新的随机变量();
//初始化随机数据
var index=new int[10];//索引表
var times=新的双精度[10];//次
var values=新的双精度[10];//值
对于(int i=0;i<10;i++){
指数[i]=i;
乘以[i]=r.NextDouble();
值[i]=r.NextDouble();
}
//天真的泡沫
对于(int i=0;i<10;i++)
对于(int j=0;j<10;j++)
//比较当前索引的时间值
if(倍[指数[i]]<倍[指数[j]]){
//交换索引值(时间和值保持不变)
var temp=指数[i];
指数[i]=指数[j];
指数[j]=温度;
}
//检查结果是否正确
对于(int i=0;i<10;i++)
Console.WriteLine(times[index[i]]);
Console.ReadKey();
}

注意:我在那里使用了一个天真的气泡排序,注意。在您的例子中,插入排序可能是一个很好的选择。因为您不需要复杂的递归。

我不建议您编写自己的排序例程,因为作为Java语言的一部分提供的排序例程经过了很好的优化

解决这个问题的方法是将java.util.Arrays类中的代码复制到您自己的类中,即org.mydomain.util.Arrays。并添加一些注释,告诉自己不要使用该类,除非您必须具有要添加的附加功能。Arrays类相当稳定,因此这比看起来的要不太理想,但仍然不太理想。但是,您需要更改的方法是私有的,因此您没有真正的选择

然后,您需要创建一个如下的界面:

公共静态接口SwapHook{
无效交换(整数a,整数b);
}

然后需要将其添加到将要使用的排序方法中,以及在排序过程中调用的每个从属方法中,这些方法交换主数组中的元素。您可以安排修改后的排序例程调用钩子,然后可以实现SortHook接口,以在任何辅助(例如并行)数组中实现所需的行为

嗯。

他可能想内联swap(),因为他使用的语言不允许用户定义函数。