演算法學習筆記1語法 (C++組)

Adalight發表於2021-05-20

關於 #include <cstdio>

包含printf();和scanf();
c++中printf、scanf比cout、cin效率高很多
演算法題裡cin、cout可能超時,雖然可以優化,但是優化之後還是比不上scanf和printf。

第一章 演算法入門及簡單的順序結構

程式設計是一種控制計算機的方式,和我們平時雙擊開啟檔案、關機、重啟沒有任何區別。

1.變數的定義

變數必須先定義,才可以使用。不能重名。

變數定義的方式:

image

常用變數型別及範圍:

image

2.輸入輸出

整數的輸入輸出:

image

字串的輸入輸出:

image

輸入輸出多個不同型別的變數:

image

3.表示式

整數的加減乘除四則運算:

image
image

浮點數(小數)的運算:

image

整型變數的自增、自減:

image

變數的型別轉換:

image

4.順序語句

(1)輸出第二個整數:

image

(2)計算 (a + b) * c的值

image

(3)帶餘除法

image

(4)求反三位數:

image

(5)交換兩個整數

(6)輸出菱形

image

第二章 printf語句與C++中的判斷結構

學習語言最好的方式就是實踐,每當掌握一個新功能時,就要立即將這個功能應用到實踐中。

一、printf輸出格式

注意:使用printf 時最好新增標頭檔案 #include

image

1.int、float、double、char等型別的輸出格式:

(1)Int:%d
(2)Float: %f, 預設保留6位小數
(3)Double: %lf, 預設保留6位小數
(4)Char: %c, 回車也是一個字元,用’\n’表示
image

2.所有輸出的變數均可包含在一個字串中:

image

練習:輸入一個字元,用這個字元輸出一個菱形:

image

練習:輸入一個整數,表示時間,單位是秒。輸出一個字串,用”時:分:秒”的形式表示這個時間。

image

3.擴充套件功能

(1)Float, double等輸出保留若干位小數時用:%.4f, %3lf

image

(2)最小數字寬度

a.%8.3f, 表示這個浮點數的最小寬度為8,保留3位小數,當寬度不足時在前面補空格。

image

b.%-8.3f,表示最小寬度為8,保留3位小數,當寬度不足時在後面補上空格

image

c.%08.3f, 表示最小寬度為8,保留3位小數,當寬度不足時在前面補上0

image

二、if 語句

1. 基本if-else語句

當條件成立時,執行某些語句;否則執行另一些語句。

image

Else 語句可以省略:

image

當只有一條語句時,大括號可以省略:

image

練習:輸入一個整數,輸出這個數的絕對值。

image

練習:輸入兩個整數,輸出兩個數中較大的那個。

image
If-else語句內部也可以是if-else語句。

練習:輸入三個整數,輸出三個數中最大的那個。

image

2. 常用比較運算子

(1) 大於 >
(2) 小於 <
(3) 大於等於 >=
(4) 小於等於 <=
(5) 等於 ==
(6) 不等於 !=
image

3.If-else 連寫:

輸入一個0到100之間的分數,
如果大於等於85,輸出A;
如果大於等於70並且小於85,輸出B;
如果大於等於60並且小於70,輸出C;
如果小於60,輸出 D;
image

練習:

1.簡單計算器輸入兩個數,以及一個運算子+, -, *, /,輸出這兩個數運算後的結果。
當運算子是/,且除數是0時,輸出”Divided by zero!”; 當輸入的字元不是+, -, *, /時,輸出”Invalid operator!”。
image
2.判斷閏年。閏年有兩種情況:
(1)能被100整除時,必須能被400整除;
(2)不能被100整除時,被4整除即可。
輸入一個年份,如果是閏年輸出yes,否則輸出no。

三、條件表示式

(1) 與 &&
(2) 或 ||
(3) 非

例題:輸入三個數,輸出三個數中的最大值。

image

練習:用一條if語句,判斷閏年。

image

第三章 C++中的迴圈結構

學習程式語言語法是次要的,思維是主要的。如何把頭腦中的想法變成簡潔的程式碼,至關重要。

學習迴圈語句只需要抓住一點——程式碼執行順序!

一、while迴圈

可以簡單理解為迴圈版的if語句。If語句是判斷一次,如果條件成立,則執行後面的語句;while是每次判斷,如果成立,則執行迴圈體中的語句,否則停止。

image

練習:求1~100中所有數的立方和。

image

練習:求斐波那契數列的第n項。f(1)=1, f(2)=1, f(3)=2, f(n)=f(n-1) + f(n-2)。

image

死迴圈:迴圈永久執行,無法結束。我們要避免寫出死迴圈。

image

二、do while迴圈

do while迴圈不常用。
do while語句與while語句非常相似。唯一的區別是,do while語句限制性迴圈體後檢查條件。不管條件的值如何,我們都要至少執行一次迴圈。
image

三、for 迴圈

基本思想:把控制迴圈次數的變數從迴圈體中剝離。

for (init-statement ; condition; expression)
{
statement
}
init-statement可以是宣告語句、表示式、空語句,一般用來初始化迴圈變數;
condition 是條件表示式,和while中的條件表示式作用一樣;可以為空,空語句表示true
expression 一般負責修改迴圈變數,可以為空
image

練習:求1~100中所有數的立方和。

練習:求斐波那契數列的第n項。f(1)=1, f(2)=1, f(3)=2, f(n)=f(n-1) + f(n-2)。

init-statement可以定義多個變數,expression也可以修改多個變數。

例如求 1 * 10 + 2 * 8 + 3 * 7 + 4 * 6:
image

四、跳轉語句

1.break

可以提前從迴圈中退出,一般與if語句搭配。
例題:判斷一個大於1的數是否是質數:
image

2.continue

可以直接跳到當前迴圈體的結尾。作用與if語句類似。
例題:求1~100中所有偶數的和。
image

五、多層迴圈

image

練習:列印1~100中的所有質數

image

練習:輸入一個n,列印n階菱形。n是奇數。

n=9時的結果:
image
image

第四章 C++中的陣列

程式 = 邏輯 + 資料,陣列是儲存資料的強而有力的手段。

1.一維陣列

1.1陣列的定義

陣列的定義方式和變數類似。
image

1.2陣列的初始化

在main函式內部,未初始化的陣列中的元素是隨機的。
image

1.3訪問陣列元素

通過下標訪問陣列。
image

練習題1: 使用陣列實現求斐波那契數列的第N項。

image

練習題2:輸入一個n,再輸入n個整數。將這n個整數逆序輸出。

image

練習題3:輸入一個n,再輸入n個整數。將這個陣列順時針旋轉k(k <= n)次,最後將結果輸出。

image

練習題4:輸入n個數,將這n個數按從小到大的順序輸出。

image

練習題5:計算2的N次方。N <= 10000

image

2.多維陣列

多維陣列就是陣列的陣列。

Int a[3][4]; // 大小為3的陣列,每個元素是含有4個整數的陣列。

Int arr[10][20][30] = {0}; // 將所有元素初始化為0
// 大小為10的陣列,它的每個元素是含有4個整數的陣列
// 這些陣列的元素是含有30個整數的陣列

image

練習題:輸入一個n行m列的矩陣,從左上角開始將其按回字形的順序順時針列印出來。

image

第五章 C++中的字串

字串是計算機與人類溝通的重要手段。

1.字元與整數的聯絡——ASCII碼

每個常用字元都對應一個-128~127的數字,二者之間可以相互轉化:

image

常用ASCII值:’A’-‘Z’ 是65~90,’a’-‘z’是97-122,’0’-‘9’是48-57。

字元可以參與運算,運算時會將其當做整數:

image

練習:輸入一行字元,統計出其中數字字元的個數,以及字母字元的個數。

2.字元陣列

字串就是字元陣列加上結束符’\0’。

可以使用字串來初始化字元陣列,但此時要注意,每個字串結尾會暗含一個’\0’字元,因此字元陣列的長度至少要比字串的長度多1!

image

2.1字元陣列的輸入輸出:

image
讀入一行字串,包括空格:
image

2.2字元陣列的常用操作

下面幾個函式需要引入標頭檔案:
#include <string.h>
(1)strlen(str),求字串的長度
(2)strcmp(a, b),比較兩個字串的大小,a < b 返回-1,a == b 返回0,a > b返回1。這裡的比較方式是字典序!
(3)strcpy(a, b),將字串b複製給從a開始的字元陣列。
image

2.3遍歷字元陣列中的字元:

image

練習:給定一個只包含小寫字母的字串,請你找到第一個僅出現一次的字元。如果沒有,輸出“no”。

練習:把一個字串中特定的字元全部用給定的字元替換,得到一個新的字串。

3.標準庫型別 string

可變長的字元序列,比字元陣列更加好用。需要引入標頭檔案:
#include

3.1定義和初始化

image

3.2string 上的操作

(1)string的讀寫:

image
注意:不能用printf直接輸出string,需要寫成:printf(“%s”, s.c_str());

(2)使用getline讀取一整行

image

(3)string的empty和size操作(注意size是無符號整數,因此 s.size() <= -1一定成立):

image

(4)string 的比較:

支援 > < >= <= == !=等所有比較操作,按字典序進行比較。

(5)為string物件賦值:

string s1(10, ‘c’), s2;// s1的內容是 cccccccccc;s2是一個空字串
s1 = s2;// 賦值:用s2的副本替換s1的副本// 此時s1和s2都是空字串

(6)兩個string物件相加:

string s1 = “hello,  ”, s2 = “world\n”;
string s3 = s1 + s2;// s3的內容是 hello, world\n
s1 += s2;// s1 = s1 + s2

(7)字面值和string物件相加:

做加法運算時,字面值和字元都會被轉化成string物件,因此直接相加就是將這些字面值串聯起來:

string s1 = “hello”, s2 = “world”;// 在s1和s2中都沒有標點符號
string s3 = s1 + “, “ + s2 + ‘\n’;

當把string物件和字元字面值及字串字面值混在一條語句中使用時,必須確保每個加法運算子的兩側的運算物件至少有一個是string:

string s4 = s1 + “, “;	// 正確:把一個string物件和有一個字面值相加
string s5 = “hello” +”, “; // 錯誤:兩個運算物件都不是string

string s6 = s1 + “, “ + “world”;  // 正確,每個加法運算都有一個運算子是string
string s7 = “hello” + “, “ + s2;  // 錯誤:不能把字面值直接相加,運算是從左到右進行的

3.3 處理string物件中的字元

可以將string物件當成字元陣列來處理:

image

或者使用基於範圍的for語句:

image

練習:密碼翻譯,輸入一個只包含小寫字母的字串,將其中的每個字母替換成它的後繼字母,如果原字母是’z’,則替換成’a’。

練習:輸入兩個字串,驗證其中一個串是否為另一個串的子串。

第六章 C++中的函式

函式讓程式碼變得更加簡潔。

1.函式基礎

一個典型的函式定義包括以下部分:返回型別、函式名字、由0個或多個形參組成的列表以及函式體。

1.1編寫函式

我們來編寫一個求階乘的程式。程式如下所示:

int fact(int val)
{
    int ret = 1;
    while (val > 1)
        ret *= val -- ;
    return ret;
}

函式名字是fact,它作用於一個整型引數,返回一個整型值。return語句負責結束fact並返回ret的值。

1.2呼叫函式

int main()
{
    int j = fact(5);
    cout \<\< "5! is " \<\< j \<\< endl;
    return 0;
}

函式的呼叫完成兩項工作:一是用實參初始化函式對應的形參,二是將控制權轉移給被呼叫函式。此時,主調函式的執行被暫時中斷,被調函式開始執行。

1.3形參和實參

實參是形參的初始值。第一個實參初始化第一個形參,第二個實參初始化第二個形參,依次類推。形參和實參的型別和個數必須匹配。

fact(“hello”);		// 錯誤:實參型別不正確
fact(); 			// 錯誤:實引數量不足
fact(42, 10, 0); 	// 錯誤:實引數量過多
fact(3.14); 		// 正確:該實參能轉換成int型別,等價於fact(3);

形參也可以設定預設值,但所有預設值必須是最後幾個。當傳入的實參個數少於形參個數時,最後沒有被傳入值的形參會使用預設值。

1.4函式的形參列表

函式的形參列表可以為空,但是不能省略。

void f1() {/* …. */}// 隱式地定義空形參列表
void f2(void) {/* … */} // 顯式地定義空形參列表

形參列表中的形參通常用逗號隔開,其中每個形參都是含有一個宣告符的宣告。即使兩個形參的型別一樣,也必須把兩個型別都寫出來:

int f3(int v1, v2) {/* … */} // 錯誤
int f4(int v1, int v2) {/* … */} // 正確

1.5函式返回型別

大多數型別都能用作函式的返回型別。一種特殊的返回型別是void,它表示函式不返回任何值。函式的返回型別不能是陣列型別或函式型別,但可以是指向陣列或者函式的指標。

1.6區域性變數、全域性變數與靜態變數

區域性變數只可以在函式內部使用,全域性變數可以在所有函式內使用。當區域性變數與全域性變數重名時,會優先使用區域性變數。

2.引數傳遞

2.1傳值引數

當初始化一個非引用型別的變數時,初始值被拷貝給變數。此時,對變數的改動不會影響初始值。
image

2.2傳引用引數

當函式的形參為引用型別時,對形參的修改會影響實參的值。使用引用的作用:避免拷貝、讓函式返回額外資訊。
image

2.3陣列形參

在函式中對陣列中的值的修改,會影響函式外面的陣列。

一維陣列形參的寫法:

// 儘管形式不同,但這三個print函式是等價的
void print(int *a) {/* … */}
void print(int a[]) {/* … */}
void print(int a[10]) {/* … */}

image

多維陣列形參的寫法:

// 多維陣列中,除了第一維之外,其餘維度的大小必須指定
void print(int (*a)[10]) {/* … */}
void print(int a[][10]) {/* … */}

image

3.返回型別和return語句

return 語句終止當前正在執行的函式並將控制權返回到呼叫該函式的地方。return語句有兩種形式:
return;
return expression;

3.1無返回值函式

沒有返回值的return語句只能用在返回型別是void的函式中。返回void的函式不要求非得有return語句,因為在這類函式的最後一句後面會隱式地執行return。
通常情況下,void函式如果想在它的中間位置提前退出,可以使用return語句。return的這種用法有點類似於我們用break語句退出迴圈。

void swap(int \&v1, int \&v2)
{
    // 如果兩個值相等,則不需要交換,直接退出
    if (v1 == v2)
        return;
    // 如果程式執行到了這裡,說明還需要繼續完成某些功能

    int tmp = v2;
    v2 = v1;
    v1 = tmp;
    // 此處無須顯示的return語句
}

3.2有返回值的函式

只要函式的返回型別不是void,則該函式內的每條return語句必須返回一個值。return語句返回值的型別必須與函式的返回型別相同,或者能隱式地轉換函式的返回型別。
image

4.函式遞迴

在一個函式內部,也可以呼叫函式本身。
image

第七章 類、結構體、指標、引用

類可以將變數、陣列和函式完美地打包在一起。

1.類與結構體

類的定義:

image

類中的變數和函式被統一稱為類的成員變數。

private後面的內容是私有成員變數,在類的外部不能訪問;public後面的內容是公有成員變數,在類的外部可以訪問。

類的使用:

\#include \<iostream\>

using namespace std;

const int N = 1000010;

class Person
{
    private:
        int age, height;
        double money;
        string books[100];

    public:
        string name;

        void say()
        {
            cout \<\< "I'm " \<\< name \<\< endl;
        }

        int set_age(int a)
        {
            age = a;
        }

        int get_age()
        {
            return age;
        }

        void add_money(double x)
        {
            money += x;
        }
} person_a, person_b, persons[100];

int main()
{
    Person c;

    c.name = "yxc";      // 正確!訪問公有變數
    c.age = 18;          // 錯誤!訪問私有變數
    c.set_age(18);       // 正確!set_age()是共有成員變數
    c.add_money(100);

    c.say();
    cout \<\< c.get_age() \<\< endl;

    return 0;
}

結構體和類的作用是一樣的。不同點在於類預設是private,結構體預設是public。

image

2.指標和引用

指標指向存放變數的值的地址。因此我們可以通過指標來修改變數的值。

image

陣列名是一種特殊的指標。指標可以做運算:

image

引用和指標類似,相當於給變數起了個別名。

image

3.連結串列

image

第八章 C++ STL

STL是提高C++編寫效率的一個利器。

1.#include <vector>

vector是變長陣列,支援隨機訪問,不支援在任意位置O(1)插入。為了保證效率,元素的增刪一般應該在末尾進行。

宣告

#include <vector> 標頭檔案
vector<int> a;相當於一個長度動態變化的int陣列
vector<int> b[233];相當於第一維長233,第二位長度動態變化的int陣列
struct rec{…};
vector<rec> c;自定義的結構體型別也可以儲存在vector中

size/empty

size函式返回vector的實際長度(包含的元素個數),empty函式返回一個bool型別,表明vector是否為空。二者的時間複雜度都是O(1)。
所有的STL容器都支援這兩個方法,含義也相同,之後我們就不再重複給出。

clear

clear函式把vector清空。

迭代器

迭代器就像STL容器的“指標”,可以用星號“*”操作符解除引用。
一個儲存int的vector的迭代器宣告方法為:
vector<int>::iterator it;
vector的迭代器是“隨機訪問迭代器”,可以把vector的迭代器與一個整數相加減,其行為和指標的移動類似。可以把vector的兩個迭代器相減,其結果也和指標相減類似,得到兩個迭代器對應下標之間的距離。

begin/end

begin函式返回指向vector中第一個元素的迭代器。例如a是一個非空的vector,則a.begin()與a[0]的作用相同。
所有的容器都可以視作一個“前閉後開”的結構,end函式返回vector的尾部,即第n個元素再往後的“邊界”。
a.end()與a[n]都是越界訪問,其中n=a.size()。
下面兩份程式碼都遍歷了vector<int>a,並輸出它的所有元素。

for (int I = 0; I \< a.size(); I ++) cout \<\< a[i] \<\< endl;
for (vector\<int\>::iterator it = a.begin(); it != a.end(); it ++) cout \<\< *it \<\< endl;

front/back

front函式返回vector的第一個元素,等價於a.begin() 和 a[0]。
back函式返回vector的最後一個元素,等價於
==a.end() 和 a[a.size() – 1]。

push_back() 和 pop_back()

a.push_back(x) 把元素x插入到vector a的尾部。
b.pop_back() 刪除vector a的最後一個元素。

2.#include <queue>

標頭檔案queue主要包括迴圈佇列queue和優先佇列priority_queue兩個容器。

宣告

queue\<int\> q;
struct rec{…}; queue\<rec\> q; //結構體rec中必須定義小於號
priority_queue\<int\> q;// 大根堆
priority_queue<int, vector\<int\>, greater\<int\> q;// 小根堆
priority_queue\<pair\<int, int\>\>q;

迴圈佇列 queue

push 從隊尾插入
pop 從隊頭彈出
front 返回隊頭元素
back 返回隊尾元素

優先佇列 priority_queue

push 把元素插入堆
pop 刪除堆頂元素
top 查詢堆頂元素(最大值)

3.#include <stack>

標頭檔案stack包含棧。宣告和前面的容器類似。
push 向棧頂插入
pop 彈出棧頂元素

4.#include <deque>

雙端佇列deque是一個支援在兩端高效插入或刪除元素的連續線性儲存空間。它就像是vector和queue的結合。與vector相比,deque在頭部增刪元素僅需要O(1)的時間;與queue相比,deque像陣列一樣支援隨機訪問。
[] 隨機訪問
begin/end,返回deque的頭/尾迭代器
front/back 隊頭/隊尾元素
push_back 從隊尾入隊
push_front 從隊頭入隊
pop_back 從隊尾出隊
pop_front 從隊頭出隊
clear 清空佇列

5.#include <set>

標頭檔案set主要包括set和multiset兩個容器,分別是“有序集合”和“有序多重集合”,即前者的元素不能重複,而後者可以包含若干個相等的元素。set和multiset的內部實現是一棵紅黑樹,它們支援的函式基本相同。

宣告

set\<int\> s;
struct rec{…}; set\<rec\> s;// 結構體rec中必須定義小於號
multiset\<double\> s;

size/empty/clear

與vector類似

迭代器

set和multiset的迭代器稱為“雙向訪問迭代器”,不支援“隨機訪問”,支援星號(*)解除引用,僅支援”++”和--“兩個與算術相關的操作。
設it是一個迭代器,例如set<int>::iterator it;
若把it++,則it會指向“下一個”元素。這裡的“下一個”元素是指在元素從小到大排序的結果中,排在it下一名的元素。同理,若把it--,則it將會指向排在“上一個”的元素。

begin/end

返回集合的首、尾迭代器,時間複雜度均為O(1)。
s.begin() 是指向集合中最小元素的迭代器。
s.end() 是指向集合中最大元素的下一個位置的迭代器。換言之,就像vector一樣,是一個“前閉後開”的形式。因此--s.end()是指向集合中最大元素的迭代器。

insert

s.insert(x)把一個元素x插入到集合s中,時間複雜度為O(logn)。
在set中,若元素已存在,則不會重複插入該元素,對集合的狀態無影響。

find

s.find(x) 在集合s中查詢等於x的元素,並返回指向該元素的迭代器。若不存在,則返回s.end()。時間複雜度為O(logn)。

lower_bound/upper_bound

這兩個函式的用法與find類似,但查詢的條件略有不同,時間複雜度為 O(logn)。
s.lower_bound(x) 查詢大於等於x的元素中最小的一個,並返回指向該元素的迭代器。
s.upper_bound(x) 查詢大於x的元素中最小的一個,並返回指向該元素的迭代器。

erase

設it是一個迭代器,s.erase(it) 從s中刪除迭代器it指向的元素,時間複雜度為O(logn)
設x是一個元素,s.erase(x) 從s中刪除所有等於x的元素,時間複雜度為O(k+logn),其中k是被刪除的元素個數。

count

s.count(x) 返回集合s中等於x的元素個數,時間複雜度為 O(k +logn),其中k為元素x的個數。

6.#include <map>

map容器是一個鍵值對key-value的對映,其內部實現是一棵以key為關鍵碼的紅黑樹。Map的key和value可以是任意型別,其中key必須定義小於號運算子。

宣告

map<key_type, value_type> name;
例如:

map\<long, long, bool\> vis;
map\<string, int\> hash;
map\<pair\<int, int\>, vector\<int\>\> test;

size/empty/clear/begin/end均與set類似。

Insert/erase

與set類似,但其引數均是pair<key_type, value_type>。

find

h.find(x) 在變數名為h的map中查詢key為x的二元組。

[]操作符

h[key] 返回key對映的value的引用,時間複雜度為O(logn)。
[]操作符是map最吸引人的地方。我們可以很方便地通過h[key]來得到key對應的value,還可以對h[key]進行賦值操作,改變key對應的value。

第九章 位運算與常用庫函式

C++幫我們實現好了很多有用的函式,我們要避免重複造輪子。

1.位運算

& 與
| 或
~ 非
^ 異或
>> 右移
<< 左移

常用操作:

(1)求x的第k位數字 x >> k & 1
(2)lowbit(x) = x & -x,返回x的最後一位1

2.常用庫函式、

(1)reverse 翻轉

翻轉一個vector:
reverse(a.begin(), a.end());
翻轉一個陣列,元素存放在下標1~n:
reverse(a + 1, a + 1 + n);

(2)unique 去重

返回去重之後的尾迭代器(或指標),仍然為前閉後開,即這個迭代器是去重之後末尾元素的下一個位置。該函式常用於離散化,利用迭代器(或指標)的減法,可計算出去重後的元素個數。
把一個vector去重:
int m = unique(a.begin(), a.end()) – a.begin();
把一個陣列去重,元素存放在下標1~n:
int m = unique(a + 1, a + 1 + n) – (a + 1);

(3)random_shuffle 隨機打亂

用法與reverse相同

(4)sort

對兩個迭代器(或指標)指定的部分進行快速排序。可以在第三個引數傳入定義大小比較的函式,或者過載“小於號”運算子。

把一個int陣列(元素存放在下標1~n)從大到小排序,傳入比較函式:

int a[MAX_SIZE];
bool cmp(int a, int b) {return a > b; }
sort(a + 1, a + 1 + n, cmp);

把自定義的結構體vector排序,過載“小於號”運算子:

struct rec{ int id, x, y; }
vector\<rec\> a;
bool operator \<(const rec &a, const rec &b) {
return a.x \< b.x \|\| a.x == b.x \&\& a.y \< b.y;
}
sort(a.begin(), a.end());

(5)lower_bound/upper_bound 二分

lower_bound 的第三個引數傳入一個元素x,在兩個迭代器(指標)指定的部分上執行二分查詢,返回指向第一個大於等於x的元素的位置的迭代器(指標)。
upper_bound 的用法和lower_bound大致相同,唯一的區別是查詢第一個大於x的元素。當然,兩個迭代器(指標)指定的部分應該是提前排好序的。

在有序int陣列(元素存放在下標1~n)中查詢大於等於x的最小整數的下標:

int I = lower_bound(a + 1, a + 1 + n,. x) – a;

在有序vector<int> 中查詢小於等於x的最大整數(假設一定存在):

int y = *--upper_bound(a.begin(), a.end(), x);

相關文章