matlab積分演算法離散化求和_演算法學習筆記(19): 離散化
阿新 • • 發佈:2021-02-12
技術標籤:matlab積分演算法離散化求和
離散化,就是當我們只關心資料的大小關係時,用排名代替原資料進行處理的一種預處理方法。離散化本質上是一種雜湊,它在保持原序列大小關係的前提下把其對映成正整數。當原資料很大或含有負數、小數時,難以表示為陣列下標,一些演算法和資料結構(如BIT)無法運作,這時我們就可以考慮將其離散化。
在之前關於樹狀陣列的筆記中,我提到過離散化,但其實那時我所用的方法並不是很合理,因為它會把序列中相同的數對映為不同的排名。而實際上,離散化可以用STL較簡單地完成。
例如,現在我們有序列A=[10, 23, 35, 3, -40, 3]。我們先複製一個同樣的序列:
int C[MAXN];
memcpy(C, A, sizeof(A));
排序,去重:
sort(C, C + n);
int l = unique(C, C + n) - C; // l為不重複元素的數量
std::unique()的返回值是一個迭代器(對於陣列來說就是指標了),它表示去重後容器中不重複序列的最後一個元素的下一個元素。所以可以這樣作差求得不重複元素的數量。現在我們有C=[-40, 3, 10, 23, 35]。
再用一個數組,儲存A中每個元素在C中的排名:
int L[MAXN]; for (int i = 0; i < n; ++i) L[i] = lower_bound(C, C + l, A[i]) - C + 1; // 二分查詢
這樣我們就實現了原序列的離散化。得到L=[3, 4, 5, 2, 1, 2]。
因為排序和n次二分查詢的複雜度都是
,所以離散化的複雜度也是 。完整程式碼很短:int C[MAXN], L[MAXN];
// 在main函式中...
memcpy(C, A, sizeof(A)); // 複製
sort(C, C + n); // 排序
int l = unique(C, C + n) - C; // 去重
for (int i = 0; i < n; ++i)
L[i] = lower_bound(C, C + l, A[i]) - C + 1; // 查詢
離散化也不一定要從小到大排序,有時候也需要從大到小。這時在排序和查詢時相應地加上greater<int>()
Pecco:演算法學習筆記(目錄)zhuanlan.zhihu.com