【问题标题】:C++ shift values to begin of arrayC++ 将值移到数组的开头
【发布时间】:2020-04-01 03:54:24
【问题描述】:

需要移动数组开头所有小于 1 的值(没有排序,需要没有第二个数组的解决方案)

例如:

START ARRAY: {-2.12, -3, 7.36, 6.83, -1.82, 7.01}

FINISH ARRAY: {-2.12, -3, -1.82, 7.36, 6.83, 7.01}

有我的解决方案,但效果不佳,因为最终我们收到:

FINISH ARRAY: {-2.12, -3, -1.82, 6.83, 7.36, 7.01}

小于 1 的值移动到数组的开头,但 4 和 5 个元素的顺序不正确

#include <iostream>

using namespace std;

int main() {
    double arr[6] = {-2.12, -3, 7.36, 6.83, -1.82, 7.01};

    cout << "Start array: " << endl;
    for (int x = 0; x < 6; x++) {
        cout << arr[x] << ", ";
    }

    int index=0;
    double temp;
    for (int i = 0; i < 6; i++) { 
        if (arr[i] < 1) {
            temp=arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
            index++;
        }
     }
    cout << endl << "FINISH ARRAY: " << endl;
    for (int x = 0; x < 6; x++) {
        cout << arr[x] << ", ";
    }



    return 0;
}

【问题讨论】:

  • 如果不仅仅是关于解决方案,而是关于自己实现它,请尝试先学习如何使用调试器单步执行代码。然后,您可以随时判断哪里出了问题。
  • 我知道如何使用调试器,但我使用的是动态数组,而 VS Code 调试器看不到数组值
  • 我不敢相信。默认情况下,指针可能显示为值,但您应该能够展开它以显示其后面的元素。

标签: c++ arrays algorithm


【解决方案1】:

使用std::stable_partition:

std::stable_partition(std::begin(arr), std::end(arr), 
    [](double d) { return d < 1; });

如果你想自己实现它,请注意,就地稳定分区(使用比较和交换)不能比O(N log N) time 做得更好。任何运行时间为O(N) 的算法都是不正确的。

一种可能的解决方案可以通过分而治之的方法获得:

template<class It, class Pred>
It stable_partition(It first, It last, Pred pred) {
    // returns the iterator to the first element of the second group:
    // TTTTTFFFFFF
    //      ^ return value

    if (first == last)
        return last;
    if (last - first == 1) {
        if (pred(*first))     // T
            return last;      //  ^ last  
        else                  // F
            return first;     // ^ first
    }

    // Split in two halves
    const auto mid = first + (last - first) / 2;

    // Partition the left half
    const auto left = stable_partition(first, mid, pred);
    // TTTTTFFFFF
    //      ^ left
    //           ^ mid 

    // Partition the right half
    const auto right = stable_partition(mid, last, pred);
    // TTTTTFFFFF
    //      ^ right
    // ^ mid

    // Rotate the middle part: TTTTTFFFFFTTTTTFFFFF
    //                              ~~~~~~~~~~
    //                              ^ left    ^ right
    //                                   ^ mid
    const auto it =  std::rotate(left, mid, right);
    // TTTTTTTTTTFFFFFFFFFF
    //           ^ it
    return it;
}

它类似于快速排序,但这里我们实际上并不对范围进行排序。 std::rotate 本身可以通过三个反向轻松实现。

【讨论】:

    猜你喜欢
    • 2021-11-27
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    相关资源
    最近更新 更多