1. 程式人生 > 其它 >matlab積分演算法離散化求和_演算法學習筆記(19): 離散化

matlab積分演算法離散化求和_演算法學習筆記(19): 離散化

技術標籤:matlab積分演算法離散化求和

e929b7cbbc3562498d8e0abb337fc2b3.png

離散化,就是當我們只關心資料的大小關係時,用排名代替原資料進行處理的一種預處理方法。離散化本質上是一種雜湊,它在保持原序列大小關係的前提下把其對映成正整數。當原資料很大或含有負數、小數時,難以表示為陣列下標,一些演算法和資料結構(如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次二分查詢的複雜度都是

equation?tex=O%28n%5Clog+n%29 ,所以離散化的複雜度也是 equation?tex=O%28n%5Clog+n%29 。完整程式碼很短:
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 zhihu-card-default.svg