簡體   English   中英

C ++:使用STL排序以對不同列上的2d整數數組進行排序的時間復雜度

[英]C++: Time complexity of using STL's sort in order to sort a 2d array of integers on different columns

假設我們有以下2d整數數組:

1 3 3 1
1 0 2 2
2 0 3 1
1 1 1 0
2 1 1 3

我試圖創建一個實現,用戶可以在其中提供數組本身和一個字符串作為輸入。 上面示例中的字符串示例為03 ,這表示用戶希望根據第一列和第四列對數組進行排序。

因此,在這種情況下,排序結果如下:

1 1 1 0
1 3 3 1
1 0 2 2
2 0 3 1
2 1 1 3

我對STL的sort函數中使用的比較函數一無所知,但是在搜索之后,我創建了以下簡單實現:

我創建了一個名為Comparator.h的類

   class Comparator{

     private:
      std::string attr;

     public:
      Comparator(std::string attr) { this->attr = attr; }

      bool operator()(const int* first, const int* second){
       std::vector<int> left;
       std::vector<int> right;
       size_t i;
       for(i=0;i<attr.size();i++){
                left.push_back(first[attr.at(i) - '0']);
                right.push_back(second[attr.at(i) - '0']);
        }
        for(i=0;i<left.size();i++){
                if(left[i] < right[i]) return true;
                else if(left[i] > right[i]) return false;
        }
        return false;
      }

     };

我需要知道字符串中的信息,所以我需要一個該字符串是私有變量的類。 operator內部,我將有兩個參數firstsecond ,每個參數都將引用一行。 現在有了此信息,我創建了一個left向量和right向量,其中在left向量中,我只有first行的數字對排序很重要,並且由字符串變量指定;而在right向量中,我僅具有second行對排序很重要,由字符串變量指定。

然后,我進行必要的比較並返回true或false。 用戶可以通過在Sorting.cpp類中調用此函數來使用此類:

void Sorting::applySort(int **data, std::string attr, int amountOfRows){

  std::sort(data, data+amountOfRows, Comparator(attr));

 }

這是一個示例用法:

int main(void){
    //create a data[][] variable and fill it with integers
    Sorting sort;

sort.applySort(data, "03", number_of_rows);
}

我有兩個問題:

第一個問題

我的實施情況可以改善嗎? 我喜歡使用額外的變量leftright的載體,然后我有一些for循環帶來一些額外的成本來排序操作。

第二個問題

由於額外的成本,分揀的時間復雜度會變差多少? 我知道STL的sortO(n*logn) ,其中n是您要排序的整數數。 這里n具有不同的含義, n是行數,每行最多可以包含m整數,這些整數可以通過重寫operator並使用額外的變量(向量)和for循環在Comparator類中找到。

因為我不確定STL的sort是如何實現的,所以我只能做一些估算。 我的初始估計為O(n*m*log(n)) ,其中m是對排序很重要的列數,但是我不確定100%。

先感謝您

您當然可以改善比較器。 無需復制列然后進行比較。 不用比較兩個push_back調用,只需比較這些值並返回true,返回false或根據它們是較小,較大還是相等來繼續循環。

sort復雜度的相關部分是O(n * log n)比較(在C ++ 11中。C++ 03不能提供如此好的保證),其中n是要排序的元素數。 因此,假設您的比較器為O(m) ,則可以對n行進行排序。 由於attr.size() <= m ,所以您是對的。

第一個問題:不需要左和右-逐個添加元素,然后以相同順序遍歷向量。 因此,與其將值推入向量然后進行遍歷,不如在第一個周期生成它們時使用它們,就像這樣:

    for(i=0;i<attr.size();i++){
            int left = first[attr.at(i) - '0'];
            int right = second[attr.at(i) - '0'];
            if(left < right) return true;
            else if(left > right) return false;
    }

第二個問題:時間復雜度可以提高嗎? 不適用於使用直接比較的排序算法。 另一方面,您在這里解決的問題有點類似於基數排序 因此,我相信您應該能夠在O(n * m)中進行排序,其中m是排序標准的數量。

1)首先,您應該在構造函數中將字符串轉換為整數數組。 值的驗證小於列數。

(您也可以使用另一個構造函數,該構造函數將整數數組作為參數。稍有增強就是允許負值表示該列的排序順序顛倒了。在這種情況下,值將為-N ..- 1,1..N)

2)不需要中間的左右數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM