zoukankan      html  css  js  c++  java
  • 模糊排序 算法导论7.6 c++实现代码

       题目读起来有点晦涩,理解之后思路比较容易想到。其实就是排序的元素换成了闭区间,而闭区间‘相等’就是这些区间有公共的区域(等价类),这样就类似于习题7.2了,返回两个下标,它们之间是相等的元素,前面是‘较小’的区间,后面是‘较大’的区间。那么如何求公共子区间呢,我这里是从前往后遍历数组,如果有交叠,就把主元更新为重叠区域,然后再遍历,这样子如果下一个区间与主元重叠,则该区间与之前所有的区间都重叠。

       第二问中如果n个区间都有重叠部分,即n个元素都‘相等’,很显然只需要O(n)的时间,因为第一次划分就结束了排序。

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef pair<int, int> Interval;
    //判断两个区间是否重叠
    bool Intersect(Interval i1, Interval i2){
        return i1.second >= i2.first&&i1.first <= i2.second;
    }
    
    pair<int,int> Interval_P(Interval *inv, int p, int r){
        int pivot = p + rand() % (r - p + 1);
        Interval temp = inv[pivot];
        swap(inv[pivot], inv[r]);
        for (int k = 0; k < r; ++k){
            if (Intersect(inv[k], temp)){
                temp.first = max(inv[k].first, temp.first);
                temp.second = min(inv[k].second, temp.second);
            }
        }
        int i = p - 1, j = p;
        for (; j < r; ++j){
            if (!Intersect(inv[j],temp))
                if (inv[j].first < temp.first){
                    ++i;
                    swap(inv[j], inv[i]);
                }
        }
        int t = i+1;
        for (j = i + 1; j < r; ++j){
            if (Intersect(inv[j], temp))
            {
                ++i;
                swap(inv[i], inv[j]);
            }
        }
        swap(inv[i + 1], inv[r]);
        return{ t, i + 1 };
    }
    
    
    
    
    //输入的是数组下标
    void Interval_QS(Interval *inv, int p, int r){
        if (p >= r)
            return;
        pair<int,int> pa= Interval_P(inv, p, r);
        Interval_QS(inv, p, pa.first - 1);
        Interval_QS(inv, pa.second + 1, r);
    }
    //复习一下尾递归,栈深度的问题
    void Tail_IQS(Interval *inv, int p, int r){
        while (p < r){
            pair<int, int> pa = Interval_P(inv, p, r);
            Tail_IQS(inv, p, pa.first - 1);
            p = pa.second + 1;
        }
    }
    
    int main(){
        Interval inv[12] = { { 1, 2 }, { 2, 3 }, { 3, 9 }, { 2, 3 }, { 5, 7 }, { 1, 9 }, { 2, 6 }, { 0, 1 }, { 1, 1 }, { 2, 2 }, { 3, 4 }, {9,10} };
        Tail_IQS(inv, 0, 11);
        for (int i = 0; i < 12; ++i)
            cout << inv[i].first << " " << inv[i].second<<endl;
    }
  • 相关阅读:
    常用日期函数介绍
    常用数学函数介绍
    oracle 常用sql字符函数介绍
    centos6.5 相关命令
    Kettle5.4.0 java.lang.OutOfMemoryError
    oracle多表连接方式Hash Join Nested Loop Join Merge Join
    CONNECT_BY_ROOT
    设置Oracle PL/SQL时间显示格式NLS_TIMESTAMP_FORMAT
    INSTR代替NOT LIKE
    多表插入
  • 原文地址:https://www.cnblogs.com/Nastukashii/p/4402163.html
Copyright © 2011-2022 走看看