1. 程式人生 > 實用技巧 >Vue或JS的浮點型乘除法無法精確計算

Vue或JS的浮點型乘除法無法精確計算

技術標籤:演算法筆記

優先佇列

priority_queue:優先佇列,底層用來進行實現的。在優先佇列中,隊首元素一定是當前佇列中優先順序最高的那一個

例如,定義好優先順序:
桃子(優先順序3)
梨子(優先順序4)
蘋果(優先順序1)
那麼出隊順序為梨子(4)->桃子(3)->蘋果(1)

可以在任何時候往優先佇列裡面加入(push)元素,而優先佇列底層的資料結構堆(heap)可以隨時呼叫結構,使得每次的隊首元素都是優先順序最大的

priority_queue的定義

新增標頭檔案#include

priority_queue <typename> name;

priority_queue容器內元素的訪問

只能通過top()函式來訪問隊首元素,也就是優先順序最高的元素。

#include <stdio.h>
#include <queue>
using namespace std;

int main()
{
    priority_queue<int> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n", q.top());
    return 0;
}
4

priority_queue常用函式例項解析

(1)push()
push(x)將令x入隊,時間複雜度為O(logN),其中N為當前優先佇列中的元素個數。

(2)top()
top()可以獲得隊首(即堆頂元素),時間複雜度為O(1)。

(3)pop()
pop()令隊首元素出隊,時間複雜度為O(logN),其中N為當前優先佇列中的元素個數。

#include <stdio.h>
#include <queue>
using namespace std;

int main()
{
    priority_queue<int> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n", q.top());
	q.pop(); // 令隊首出隊
	printf
("%d\n", q.top()); return 0; }
4
3

(4)empty()
empty()檢測優先佇列是否為空,返回true則空,返回false則非空,時間複雜度O(1)。

#include <stdio.h>
#include <queue>
using namespace std;

int main()
{
    priority_queue<int> q;
	if(q.empty() == true)
	{
		printf("Empty\n");
	}
	else
	{
		printf("Not Empty\n");
	}
	q.push(1);
	if(q.empty() == true)
	{
		printf("Empty\n");
	}
	else
	{
	    printf("Not Empty\n");
	}
	return 0;
}
Empty
Not Empty

(5)size()
size()返回優先佇列內元素的個數,時間複雜度為O(1)

#include <stdio.h>
#include <queue>
using namespace std;

int main()
{
    priority_queue<int> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n", q.size()); //優先佇列中有三個元素
	return 0;
}
3

priority_queue內元素優先順序的設定

(1)基本資料型別的優先順序設定
int,double,char優先順序設定一般是數字大的優先順序越高,(char為字典序最大的)

priority_queue<int> q;

第二種定義方式多兩個引數
vector:填寫的是來承載底層資料結構堆(heap)的容器
less:對第一個引數的比較類,表示的數字越大的優先順序越大

priority_queue<int, vector<int>, less<int>> q;

greater表示數字小的優先順序越大

priority_queue<int, vector<int>, greater<int>> q;

示例:

#include <stdio.h>
#include <queue>
using namespace std;

int main()
{
    priority_queue<int, vector<int>, greater<int>> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n", q.top()); 
	return 0;
}
1

(2)結構體的優先順序設定
通過過載“<”來改變小於號功能,使用友元函式來對其過載。

#include <iostream>
#include <string>
#include <queue>
#include <vector>
using namespace std;

struct fruit
{
	string name;
	int price;
	friend bool operator < (fruit f1, fruit f2)
	{
		return f1.price > f2.price;
	}
}f1, f2, f3;

int main()
{
    priority_queue<fruit> q;
	f1.name = "桃子";
	f1.price = 3;
	f2.name = "梨子";
	f2.price = 4;
	f3.name = "蘋果";
	f3.price = 1;
	q.push(f1);
	q.push(f2);
	q.push(f3);
	cout << q.top().name << " " << q.top().price << endl;
	return 0;
}
蘋果 1

類比sort中的cmp函式,把friend去掉,把小於改成括號,然後把過載的函式寫在結構體外面,同時將其用struct包裝起來。

#include <iostream>
#include <string>
#include <queue>
#include <vector>
using namespace std;

struct fruit
{
	string name;
	int price;
}f1, f2, f3;

struct cmp
{
	bool operator () (fruit f1, fruit f2)
	{
		return f1.price > f2.price;
	}
};

int main()
{
    priority_queue<fruit, vector<fruit>, cmp> q;
	f1.name = "桃子";
	f1.price = 3;
	f2.name = "梨子";
	f2.price = 4;
	f3.name = "蘋果";
	f3.price = 1;
	q.push(f1);
	q.push(f2);
	q.push(f3);
	cout << q.top().name << " " << q.top().price << endl;
	return 0;
}
蘋果 1

如果結構體的資料龐大,建議使用引用來提高效率,此時比較類的引數中需要加上const和&

friend bool operator < (fruit &f1, fruit &f2)
{
	return f1.price > f2.price;
}
bool operator () (fruit &f1, fruit &f2)
{
	return f1.price > f2.price;
}

priority_queue的常見用途

可以解決一些貪心問題,也可以對Dijkstra演算法進行優化,但使用top()前,必須用empty()判斷優先佇列是否為空,否則可能因為隊空出現錯誤。