[英]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
內部,我將有兩個參數first
和second
,每個參數都將引用一行。 現在有了此信息,我創建了一個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);
}
我有兩個問題:
第一個問題
我的實施情況可以改善嗎? 我喜歡使用額外的變量left
和right
的載體,然后我有一些for循環帶來一些額外的成本來排序操作。
第二個問題
由於額外的成本,分揀的時間復雜度會變差多少? 我知道STL的sort
是O(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.