C ++ - 如何在循环中对半随机数组进行排序

时间:2017-08-16 09:14:01

标签: c++ loops sorting

我的代码中有一个for循环,每次都会生成一个数字数组:

1,2,3,4

以及下一轮for

2.001,4.008,1.002,2.099

正如您所看到的,每个元素都接近前一个元素,但它已经改变了顺序。这个循环运行了数千次,我需要看看这些值如何变化,但随着它们改变顺序,这是不可能的。

如何对它们进行排序?

我的尝试:

1 - 我尝试使用BubbleSort每次从最大数字到最小数字进行排序。如果元素全部增加或减少,这将工作正常。但是当它们中的一些增加而一些减少时却不会。

2 - 我想到了一种存储第一轮循环元素的方法,并将它们与下一轮进行比较,并改变元素的顺序,使它们与第一轮相比变化最小接下来轮次等等。但我无法编写一个可行的代码来完成它。

修改 我的代码是一个非常大而复杂的代码,我确信复制它只会增加混乱。但这是一个示例代码:

for(x=50;x=65;x+=0.01){
    for(i=0;i<100;i++) w[i] = SomeCalculations(i);
    output<<x<<"    "<<w[1]<<endl;
    output<<x<<"    "<<w[2]<<endl;
    ...
}

2 个答案:

答案 0 :(得分:2)

您可以监控每个特征值的差异(一阶导数)。然后,你可以继续“追踪”特征值,即使它是相交的,也可以通过对最接近的衍生物进行有根据的猜测来进行相交。

为此,我们需要一个距离函数(或成本函数)。一个这样的例子:

double dist(Eigenvalue e1, Eigenvalue e2) {
    x_dist = abs(e1.x - e2.x);
    dx_dist = abs(e1.dx - e2.dx);

    return x_dist + dx_dist;  // example distance function
}

struct Eigenvalue {
    int id;     // unique identifier for eigenvalue
    double x;   // actual value
    double dx;  // first order derivative
}

我们现在匹配彼此之间最小距离的特征值对:

void track_evals(std::vector<Eigenvalues>& evals,
                 const std::vector<Eigenvalues>& old_evals) {
    // Loop through new eigenvalues (evals) and match with
    // old eigenvalues (old_evals)
    for (auto& e : evals) {
        // Find closest match
        auto old = std::min_element(old_evals.begin(), old_evals.end(),
            [e](const Eigenvalue& a, const Eigenvalue& b) {
                return dist(a, e) < dist(b, e); });

        // Match by copying identifier
        // You can use a dictionary or some other data structure,
        // if you prefer
        e.id = (*old).id;
    }
}

当然,要使所有这些工作正常,您需要保持Eigenvalue s的正确值:

std::vector<Eigenvalue> evals;
std::vector<Eigenvalue> old_evals;

// Precompute eigenvalues
evals = SomeCalculations(0);

// Assign unique identifiers
int id = 0;
for (auto& e : evals) {
    e.id = id++;
}

// Your for loop
for (int i = 1; i < 100; i++) {
    // Save old eigenvalues
    std::swap(old_evals, evals);

    // Perform SomeCalculations() and update evals
    evals = SomeCalculations(i);

    // Also update derivatives (dx) for each of the evals!
    auto old = old_evals.begin();
    for (auto& e : evals) {
        e.dx = e.x - (*old++).x;
    }

    // Track
    track_evals(evals, old_evals);

    // Sort evals into same order (if desired)
    std::sort(evals.begin(), evals.end(),
        [](Eigenvalue& a, Eigenvalue& b) { return a.id < b.id; }); 
}

这种方法并非万无一失。可能存在碰撞,在这种情况下,您可能想尝试更多的衍生物订单或尝试降低特征值变化的速度。

答案 1 :(得分:0)

使用std::sort

std::sort(std::begin(w), std::end(w));

for (auto a : w) {
    output << x << "    "<< a << endl;
}