【问题标题】:Table cells / 2d array sorting algorithm表格单元格/二维数组排序算法
【发布时间】:2018-07-05 10:17:16
【问题描述】:

是否有一种算法可以帮助将左表(它是标量或对象的多维数组的抽象)排序到下方,以便结果与右表一样,因为可用深度可能有限在右表中(例如最多 30 行)?

还有稍微复杂一点的问题(单元格中的第一个键优先于另一个):

编辑:还有另一个复杂程度(如果可以安全地合并行/级别以防止冗余):

【问题讨论】:

  • 对每一列进行排序,然后使用与归并排序相同的算法来确定输出。
  • 根据项目的索引对每一列进行排序,例如 1 出现在第一个索引处,最大值出现在最后一个索引处。总复杂度为(列数 x quickshort)

标签: php python c++ algorithm sorting


【解决方案1】:

每列中的元素是否限制了列的深度?如果是这样,只需遍历多维数组的每一列并将元素放在相应的行中。如果您分配更多内存,或者您可以通过交换(仍然是 O(n))就地执行此操作,则执行此操作很简单。您可以在事后应用更复杂的分组。

【讨论】:

    【解决方案2】:

    一个可能的解决方案是这样的:

    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    using Column = std::vector<int>;
    using Matrix = std::vector<Column>;
    
    Column max_col(const Matrix &m) {
        return *std::max_element(m.begin(), m.end(),
                                 [](auto& lhs, auto& rhs)
                                 {
                                     return lhs.size() < rhs.size();
                                 });
    }
    
    bool is_element_in_next_rows(const Matrix &m, int element,Column::size_type row) {
        for (auto& col : m) {
            if (row >= col.size()) continue; // out of range
            if (*std::lower_bound(col.begin()+row+1,col.end(),element) == element) {
                return true;
            }
        }
        return false;
    }
    
    int min_element_in_row(const Matrix &m, Column::size_type row) { 
        int min_element = max_col(m)[row];
        for (auto& col : m) {
            if (row >= col.size()) continue; // out of range
            if (col[row] != 0) min_element = std::min(min_element, col[row]);
        }
        return min_element;
    }
    
    void print_elements(const Matrix &m) {
        for (auto& i : m) {
            for (auto& j : i) {
                std::cout << j << " ";
            }
            std::cout << std::endl;
        }
    }
    
    void organize_elements(Matrix &m) {
        for (auto& col : m) {
            std::sort(col.begin(),col.end());
        }
        auto current_max_col = max_col(m);
        for (Column::size_type row{0}; current_max_col.begin()+row!=current_max_col.end(); ++row) {
            int min_element = min_element_in_row(m,row);
            for(auto& col : m) {
                if (row >= col.size()) continue; // out of range
                int candidate = col[row];
                if (candidate > min_element) {
                    if (is_element_in_next_rows(m,candidate,row)) {
                        col.insert(col.begin()+row,0);
                    }
                }
            }
            current_max_col = max_col(m);
        }
    }
    
    int main() {
    
        Column c1 = {5,6,8};
        Column c2 = {2,5,3,1,4,6};
        Column c3 = {8,7,2,4,5,3,1};
    
        Matrix m;
        m.push_back(c1);
        m.push_back(c2);
        m.push_back(c3);
    
        std::cout << "original: \n";
        print_elements(m);
        organize_elements(m);
        std::cout << "organized: \n";
        print_elements(m);
        return 0;
    }
    

    输出如下:

    original: 
    5 6 8 
    7 2 5 3 1 4 6 
    8 7 2 4 5 3 1 
    organized: 
    0 0 0 0 5 6 8 
    1 2 3 4 5 6  
    1 2 3 4 5 7 8 
    

    包含对很容易,只需更改为它们完成比较功能的方式即可。我不知道这是不是你的意思。它还可以进一步优化,这是一个快速的解决方案,可以满足您的需求或激励您做出更好的解决方案。

    【讨论】:

    • 有什么方法可以在不使用lower_boundupper_bound 的情况下实现这个算法?
    • @camel_case 您可以改用std::find,但由于对向量进行了排序,因此lower_bound 和upper_bound 会更快。该函数的目的是查找元素是否在后面的行中,如果上下界相同,则表示该元素不存在。
    • @camel_case 另一种方法是将 if 语句更改为:if (std::find(col.begin()+row+1,col.end(),element) != col.end()) return true;
    • @camel_case 我刚刚意识到你也可以这样做if (*std::lower_bound(col.begin()+row+1,col.end(),element) == element)
    • max_col() 返回最高列的长度是否正确?
    猜你喜欢
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多