- [1 KMPç®æ³](#1)
* [1.1 KMPç®æ³åæ](#11)
* [1.2 KMPç®æ³åºç¨](#12)
+ [1.2.1 é¢ç®1ï¼æè½¬è¯](#121)
+ [1.2.2 é¢ç®2ï¼åæ é®é¢](#122)
- [2 bfprtç®æ³](#2)
* [2.1 bfprtç®æ³åæ](#21)
* [2.2 bfprtç®æ³åºç¨](#22)
1 KMPç®æ³
`大ååéï¼é¢è¯é«é¢^_^`
1.1 KMPç®æ³åæ
æ¥æ¾å符串é®é¢ï¼ä¾å¦æä»¬æä¸ä¸ªå符串str="abc1234efd"åmatch="1234"ãæä»¬å¦ä½æ¥æ¾stråç¬¦ä¸²ä¸æ¯å¦å
å«matchå符串çå串ï¼
> æ´åè§£æè·¯ï¼å¾ªç¯stråmatchï¼æ¨ä¸ªå¯¹æ¯ï¼æå·®æ
åµä¸ºO(N*M)ãæ¶é´å¤æåº¦ä¸ºO(N*M)
> KMPç®æ³ï¼å¨N大äºMæ¶ï¼å¯ä»¥å¨æ¶é´å¤æåº¦ä¸ºO(N)è§£å³æ¤ç±»é®é¢
æä»¬å¯¹strè®°å½åç¬¦åæ åçåç¼åç¼æå¤§å¹é
é¿åº¦ï¼ä¾å¦str="abcabck"
1ã对äºkä½ç½®åçå符ï¼ååç¼é¿åº¦å1æ¶ï¼åç¼ä¸º"a"åç¼ä¸º"c"ä¸ç¸ç
2ã对äºkä½ç½®åçå符ï¼ååç¼é¿åº¦å2æ¶ï¼åç¼ä¸º"ab"åç¼ä¸º"bc"ä¸ç¸ç
3ã对äºkä½ç½®åçå符ï¼ååç¼é¿åº¦å3æ¶ï¼åç¼ä¸º"abc"åç¼ä¸º"abc"ç¸ç
4ã对äºkä½ç½®åçå符ï¼ååç¼é¿åº¦å4æ¶ï¼åç¼ä¸º"abca"åç¼ä¸º"cabc"ä¸ç¸ç
5ã对äºkä½ç½®åçå符ï¼ååç¼é¿åº¦å5æ¶ï¼åç¼ä¸º"abcab"åç¼ä¸º"bcabc"ä¸ç¸ç
==注æååç¼é¿åº¦ä¸å¯åkä½ç½®åçæ´ä½é¿åº¦6ãé£ä¹æ¤æ¶kä½ç½®åçæå¤§å¹é
é¿åº¦ä¸º3==
æä»¥ï¼ä¾å¦"aaaaaab","b"çææ 为6ï¼é£ä¹"b"åæ åçååç¼æå¤§å¹é
é¿åº¦ä¸º5
æä»¬å¯¹match建ç«åæ ååç¼æå¤§å¹é
é¿åº¦æ°ç»ï¼æ¦å¿µä¸åå¨ç设置为-1ï¼ä¾å¦0ä½ç½®å没æå符串ï¼å°±ä¸º-1ï¼1ä½ç½®ååªæä¸ä¸ªå符ï¼ååç¼æ æ³åååæ åå符串ç¸çï¼è§å®ä¸º0ãä¾å¦"aabaabc"ï¼nextArr[]为[-1,0,1,0,1,2,3]
> æ´åæ¹æ³ä¹æä»¥æ
¢ï¼æ¯å ä¸ºæ¯æ¬¡æ¯å¯¹ï¼å¦æmatchçiä½ç½®åé½åstrå¹é
ä¸äºï¼ä½æ¯matchçi+1ä½ç½®æ²¡å¹é
æåãé£ä¹strä¼åéå°ç¬¬ä¸æ¬¡å¹é
çä¸ä¸ä¸ªä½ç½®ï¼matchç´æ¥åéå°0ä½ç½®å次æ¯å¯¹ãstråmatchåéçä½ç½®å¤ªå¤ï¼ä¹åçä¿¡æ¯å
¨é¨ä½åºï¼æ²¡æè®°å½
> èKMPç®æ³èè¨ï¼å¦æmatchçiä½ç½®åé½åstrå¹é
ä¸äºï¼ä½æ¯matchçi+1ä½ç½®æ²¡å¹é
æåï¼é£ä¹strä½ç½®ä¸åè·³ï¼matchåè·³å°å½åi+1ä½ç½®çæå¤§ååç¼é¿åº¦çä½ç½®ä¸ï¼å»åå½åsträ½ç½®æ¯å¯¹ã
åçæ¯å¦ææä»¬å½åmatchä½ç½®i+1æ¯å¯¹å¤±è´¥äºï¼æä»¬è·³å°æå¤§ååç¼é¿åº¦çä¸ä¸ä¸ªä½ç½®å»åå½åä½ç½®æ¯å¯¹ï¼å¦æè½å¹é
ä¸ï¼ç±äºi+1ä½ç½®ä¹åé½å¹é
çä¸ï¼é£ä¹matchçæå¤§åç¼é¿åº¦ä¹æ¯å¯¹æåï¼å¯ä»¥è¢«æä»¬å©ç¨èµ·æ¥ãæ¿æ¢æmatchçåç¼é¿åº¦ä¸å»ç»§ç»å¯¹æ¯ï¼èµ·å°å éçææ
é£ä¹ä¸ºä»ä¹stråmatchæåä¸ä¸ªä¸ç¸ççä½ç½®ï¼ä¹åçä½ç½®æ æ³é
åºmatchï¼å¯ä»¥åè¯ï¼å¦æå¯ä»¥é
ç½®åºæ¥ï¼é£ä¹è¯¥ä¸²ç头信æ¯åmatchç头信æ¯ç¸çï¼å¾åºå卿¯matchå½åä¸çä½ç½®æå¤§ååç¼è¿è¦å¤§çååç¼ï¼çç¾
Code:
```Java
public class Code01_KMP {
// O(N)
public static int getIndexOf(String s, String m) {
if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
return -1;
}
char[] str = s.toCharArray();
char[] match = m.toCharArray();
int x = 0; // strä¸å½åæ¯å¯¹å°çä½ç½®
int y = 0; // matchä¸å½åæ¯å¯¹å°çä½ç½®
// matchçé¿åº¦Mï¼M <= N O(M)
int[] next = getNextArray(match); // next[i] matchä¸iä¹åçå符串match[0..i-1],æé¿ååç¼ç¸ççé¿åº¦
// O(N)
// xå¨strä¸ä¸è¶çï¼yå¨matchä¸ä¸è¶ç
while (x < str.length && y < match.length) {
// 妿æ¯å¯¹æåï¼xåyå
±åå¾åèªçä¸ä¸ä¸ªä½ç½®ç§»å¨
if (str[x] == match[y]) {
x++;
y++;
} else if (next[y] == -1) { // 表示yå·²ç»æ¥å°äº0ä½ç½® y == 0
// stræ¢ä¸ä¸ä¸ªä½ç½®è¿è¡æ¯å¯¹
x++;
} else { // yè¿å¯ä»¥éè¿æå¤§ååç¼é¿åº¦å¾åç§»å¨
y = next[y];
}
}
// 1ã xè¶çï¼y没æè¶çï¼æ¾ä¸å°ï¼è¿å-1
// 2ã x没è¶çï¼yè¶çï¼é
åº
// 3ã xè¶çï¼yè¶ç ï¼é
åºï¼strçæ«å°¾ï¼çäºmatch
// åªè¦yè¶çï¼å°±é
åºäºï¼é
åºçä½ç½®çäºstræ¤æ¶æå¨çä½ç½®xï¼åå»yçé¿åº¦ãå°±æ¯stråå¨å¹é
çå符串çå¼å§ä½ç½®
return y == match.length ? x - y : -1;
}
// M O(M)
public static int[] getNextArray(char[] match) {
// 妿matchåªæä¸ä¸ªå符ï¼äººä¸ºè§å®-1
if (match.length == 1) {
return new int[] { -1 };
}
// match䏿¢ä¸ä¸ªå符ï¼äººä¸ºè§å®0ä½ç½®æ¯-1ï¼1ä½ç½®æ¯0
int[] next = new int[match.length];
next[0] = -1;
next[1] = 0;
int i = 2;
// cn代表ï¼cnä½ç½®çåç¬¦ï¼æ¯å½ååi-1ä½ç½®æ¯è¾çå符
int cn = 0;
while (i < next.length) {
if (match[i - 1] == match[cn]) { // è·³åºæ¥çæ¶å
// next[i] = cn+1;
// i++;
// cn++;
// çåäº
next[i++] = ++cn;
// 跳失败ï¼å¦æcn>0说æå¯ä»¥ç»§ç»è·³
} else if (cn > 0) {
cn = next[cn];
// 跳失败ï¼è·³å°å¼å¤´ä»ç¶ä¸ç
} else {
next[i++] = 0;
}
}
return next;
}
// for test
public static String getRandomString(int possibilities, int size) {
char[] ans = new char[(int) (Math.random() * size) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (char) ((int) (Math.random() * possibilities) + 'a');
}
return String.valueOf(ans);
}
public static void main(String[] args) {
int possibilities = 5;
int strSize = 20;
int matchSize = 5;
int testTimes = 5000000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
String str = getRandomString(possibilities, strSize);
String match = getRandomString(possibilities, matchSize);
if (getIndexOf(str, match) != str.indexOf(match)) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}
```
1.2 KMPç®æ³åºç¨
1.2.1 é¢ç®1ï¼æè½¬è¯
ä¾å¦Str1="123456",对äºStr1çæè½¬è¯ï¼å符串æ¬èº«ä¹æ¯å
¶æè½¬è¯ï¼Str1="123456"çæè½¬è¯ä¸ºï¼"123456","234561","345612","456123","561234","612345"ãç»å®Str1åStr2ï¼é£ä¹å¤æè¿ä¸ªä¸¤ä¸ªå符串æ¯å¦äºä¸ºæè½¬è¯ï¼æ¯è¿åtrueï¼ä¸æ¯è¿åfalse
æ´åè§£æ³æè·¯ï¼æstr1çæææè½¬è¯é½ååºæ¥ï¼çstr2æ¯å¦å¨è¿äºæè½¬è¯ä¸ãæ¨ä¸ªä¾¿å©str1ï¼å¾ªç¯æ°ç»çæ¹å¼ï¼åstr2æ¨ä¸ªæ¯å¯¹ãO(N*N)
KMPè§£æ³ï¼str1æ¼æ¥str1å¾å°str',"123456123456"ï¼æä»¬çstr2æ¯å¦æ¯str'çå串
1.2.2 é¢ç®2ï¼åæ é®é¢
ç»å®ä¸¤é¢äºåæ 头ç»ç¹ï¼node1ånode2ï¼å¤ænode2为头ç»ç¹çæ ï¼æ¯ä¸æ¯node1çæä¸ªåæ ï¼
2 bfprtç®æ³
`é¢è¯å¸¸è§`
æ
å½¢ï¼å¨ä¸ä¸ªæ åºæ°ç»ä¸ï¼æä¹æ±ç¬¬kå°çæ°ã妿éè¿æåºï¼é£ä¹æåºçå¤æåº¦ä¸ºO(n*logn)ãé®ï¼å¦ä½O(N)å¤æåº¦è§£å³è¿ä¸ªé®é¢ï¼
æè·¯1ï¼æä»¬å©ç¨å¿«æçææ³ï¼å¯¹æ°ç»è¿è¡è·å
°å½æpartionè¿ç¨ï¼æ¯ä¸æ¬¡partionå¯ä»¥å¾å°éæºæ°må°çåºåï¼çäºmçåºåï¼å¤§äºmçåºåãæä»¬çæä»¬måºåæ¯å¦å
å«æä»¬è¦æ¾ç第kå°çæ ï¼å¦ææ²¡ææ ¹æ®æ¯è¾ï¼å¨må·¦åºé´æè
må³åºé´ç»§ç»partionï¼ç´å°ç¬¬kå°çæ°å¨æä»¬ççä¸é´åºåã
å¿«ææ¯å·¦å³åºé´é½ä¼åè¿è¡partionï¼è该é®é¢åªä¼å½ä¸å¤§äºåºåæå°äºåºåï¼æ¶é´å¤æåº¦å¾å°ä¼åãT(n)=T(n/2)+O(n)ï¼æ¶é´å¤æåº¦ä¸ºO(N)ï¼ç±äºméæºéï¼æ¦çæ¶æä¸ºO(N)
æè·¯2ï¼bfprtç®æ³ï¼ä¸ä½¿ç¨æ¦çæ±ææï¼å¤æåº¦ä»ç¶ä¸¥æ ¼æ¶æå°O(N)
2.1 bfprtç®æ³åæ
éè¿ä¸æï¼å©ç¨è·å
°å½æé®é¢çæè·¯ä¸ºï¼
1ãéæºéä¸ä¸ªæ°m
2ãè¿è¡è·å
°å½æï¼å¾å°å°äºmåºåï¼çäºmåºåï¼å¤§äºmåºå
3ãindexå½ä¸å°çäºmåºåï¼è¿åçäºåºåç左边çï¼å¦åæ¯è¾ï¼è¿å
¥å°äºåºåï¼æè
大äºåºåï¼åªä¼è¿å
¥ä¸ä¸ªåºå
bfprtç®æ³ï¼åæ¤åºç¡ä¸å¯ä¸çåºå«æ¯ï¼ç¬¬ä¸æ¥ï¼å¦ä½éæ©mãå¿«æçææ³æ¯éæºéæ©ä¸ä¸ª
bfprtå¦ä½éæ©mï¼
- 1ã对arråç»ï¼5个ä¸ç»ï¼æä»¥0å°4为ä¸ç»ï¼5å°9为ä¸ç»ï¼æåä¸å¤ä¸ç»ç彿æåä¸ç»
- 2ã对å个å°ç»è¿è¡æåºãç¬¬ä¸æ¥åç¬¬äºæ¥è¿è¡ä¸æ¥ï¼æ¶é´å¤æåº¦ä¸ºO(N)
- 3ãææ¯ä¸å°ç»æåºåçä¸é´ä½ç½®çæ°æ¿åºæ¥ãæ¾å
¥ä¸ä¸ªæ°ç»ä¸m[]ãå䏿¥ç»ç§°ä¸ºbfprtæ¹æ³
- 4ã对mæ°ç»ï¼åä¸ä½æ°ï¼è¿ä¸ªæ°å°±æ¯æä»¬éè¦çm
```math
T(N) = T(N/5) + T(?) + O(N)
```
建议ç»å¾åæï¼
T(?)å¨æä»¬éæºéåmçæ¶åï¼æ¯ä¸ç¡®å®çï¼ä½æ¯å¨bfprtä¸ï¼mç左侧è崿夿å¤å°ä¸ªæ°ï¼çåäºmå³ä¾§æå°æå 个æ°ã
å设æä»¬ç»è¿åç»æ¿å°çmæ°ç»æ5个æ°ï¼ä¸ä½æ°æ¯æä»¬çmï¼å¨m[]æ°ç»ä¸ï¼å¤§äºmçæ2个ï¼å°äºmçæ2个ãå¯¹äºæ´çæ°æ®è§æ¨¡èè¨ï¼m[]çè§æ¨¡æ¯n/5ã大äºm[]ä¸ä½æ°çè§æ¨¡ä¸ºm[]çä¸å,ä¹å°±æ¯æ´ä½æ°æ®è§æ¨¡çn/10ã
ç±äºm[]ä¸çæ¯ä¸ªæ°é½æ¯ä»å°ç»ä¸éåºæ¥çï¼é£ä¹å¯¹äºæ´ä½æ°æ®è§æ¨¡èè¨ï¼å¤§äºmçæ°æ´ä½ä¸º3n/10ï¼æ¯ä¸ªn/10è§æ¨¡çæ°åå°èªå·±çå°ç»ï¼å¤§äºçäºçæ¯å°ç»æ3个ï¼
é£ä¹æå°æ3n/10çè§æ¨¡æ¯å¤§äºçäºmçï¼é£ä¹å¯¹äºæ´ä½æ°æ®è§æ¨¡èè¨æå¤æ7n/10çå°äºmçãåçæå¤æ7n/10çæ°æ®æ¯å¤§äºmç
å¯å¾ï¼
```math
T(N) = T(N/5) + T(7n/10) + O(N)
```
æ°å¦è¯æï¼ä»¥ä¸å
¬å¼æ æ³éè¿masteræ¥ç®å¤æåº¦ï¼ä½æ¯æ°å¦è¯æå¤æåº¦ä¸¥æ ¼O(N)ï¼è¯æç¥(ç®æ³å¯¼è®ºç¬¬ä¹ç« 第ä¸è)
> bfprtç®æ³å¨ç®æ³ä¸çå°ä½é常é«ï¼å®åç°åªè¦æ¶å尿们é便å®ä¹çä¸ä¸ªå¸¸æ°åç»ï¼å¾å°ä¸ä¸ªè¡¨è¾¾å¼ï¼æåæ¶æå°O(N)ï¼é£ä¹å°±å¯ä»¥éè¿O(N)çå¤æåº¦æµè¯
```Java
public class Code01_FindMinKth {
public static class MaxHeapComparator implements Comparator {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
// å©ç¨å¤§æ ¹å ï¼æ¶é´å¤æåº¦O(N*logK)
public static int minKth1(int[] arr, int k) {
PriorityQueue maxHeap = new PriorityQueue<>(new MaxHeapComparator());
for (int i = 0; i < k; i++) {
maxHeap.add(arr[i]);
}
for (int i = k; i < arr.length; i++) {
if (arr[i] < maxHeap.peek()) {
maxHeap.poll();
maxHeap.add(arr[i]);
}
}
return maxHeap.peek();
}
// æ¹åå¿«æï¼æ¶é´å¤æåº¦O(N)
public static int minKth2(int[] array, int k) {
int[] arr = copyArray(array);
return process2(arr, 0, arr.length - 1, k - 1);
}
public static int[] copyArray(int[] arr) {
int[] ans = new int[arr.length];
for (int i = 0; i != ans.length; i++) {
ans[i] = arr[i];
}
return ans;
}
// arr 第kå°çæ°: process2(arr, 0, N-1, k-1)
// arr[L..R] èå´ä¸ï¼å¦ææåºçè¯(䏿¯çç廿åº)ï¼æ¾ä½äºindexçæ°
// index [L..R]
// éè¿è·å
°å½æçä¼åï¼æ¦çæææ¶æäºO(N)
public static int process2(int[] arr, int L, int R, int index) {
if (L == R) { // L == R ==INDEX
return arr[L];
}
// 䏿¢ä¸ä¸ªæ° L + [0, R -L]ï¼éæºéä¸ä¸ªæ°
int pivot = arr[L + (int) (Math.random() * (R - L + 1))];
// è¿å以pivot为ååå¼çä¸é´åºåçå·¦å³è¾¹ç
// range[0] range[1]
// L ..... R pivot
// 0 1000 70...800
int[] range = partition(arr, L, R, pivot);
// 妿æä»¬ç¬¬kå°çæ æ£å¥½å¨è¿ä¸ªèå´å
ï¼è¿ååºåç左边ç
if (index >= range[0] && index <= range[1]) {
return arr[index];
// indexæ¯è¯¥åºåç左边çå°ï¼éå½å·¦åºé´
} else if (index < range[0]) {
return process2(arr, L, range[0] - 1, index);
// indexæ¯è¯¥åºåçå³è¾¹ç大ï¼éå½å³åºé´
} else {
return process2(arr, range[1] + 1, R, index);
}
}
public static int[] partition(int[] arr, int L, int R, int pivot) {
int less = L - 1;
int more = R + 1;
int cur = L;
while (cur < more) {
if (arr[cur] < pivot) {
swap(arr, ++less, cur++);
} else if (arr[cur] > pivot) {
swap(arr, cur, --more);
} else {
cur++;
}
}
return new int[] { less + 1, more - 1 };
}
public static void swap(int[] arr, int i1, int i2) {
int tmp = arr[i1];
arr[i1] = arr[i2];
arr[i2] = tmp;
}
// å©ç¨bfprtç®æ³ï¼æ¶é´å¤æåº¦O(N)
public static int minKth3(int[] array, int k) {
int[] arr = copyArray(array);
return bfprt(arr, 0, arr.length - 1, k - 1);
}
// arr[L..R] 妿æåºçè¯ï¼ä½äºindexä½ç½®çæ°ï¼æ¯ä»ä¹ï¼è¿å
public static int bfprt(int[] arr, int L, int R, int index) {
if (L == R) {
return arr[L];
}
// éè¿bfprtåç»ï¼æç»éåºmãä¸åäºéæºéæ©mä½ä¸ºååå¼
int pivot = medianOfMedians(arr, L, R);
int[] range = partition(arr, L, R, pivot);
if (index >= range[0] && index <= range[1]) {
return arr[index];
} else if (index < range[0]) {
return bfprt(arr, L, range[0] - 1, index);
} else {
return bfprt(arr, range[1] + 1, R, index);
}
}
// arr[L...R] äºä¸ªæ°ä¸ç»
// æ¯ä¸ªå°ç»å
鍿åº
// æ¯ä¸ªå°ç»ä¸ä½æ°æ¿åºæ¥ï¼ç»æmarr
// marrä¸çä¸ä½æ°ï¼è¿å
public static int medianOfMedians(int[] arr, int L, int R) {
int size = R - L + 1;
// æ¯å¦éè¦è¡¥æåä¸ç»ï¼ä¾å¦13ï¼é£ä¹éè¦è¡¥æåä¸ç»ï¼æåä¸ç»ä¸º3个æ°
int offset = size % 5 == 0 ? 0 : 1;
int[] mArr = new int[size / 5 + offset];
for (int team = 0; team < mArr.length; team++) {
int teamFirst = L + team * 5;
// L ... L + 4
// L +5 ... L +9
// L +10....L+14
mArr[team] = getMedian(arr, teamFirst, Math.min(R, teamFirst + 4));
}
// marrä¸ï¼æ¾å°ä¸ä½æ°ï¼åé®é¢æ¯arræ¿ç¬¬kå°çæ°ï¼è¿éæ¯ä¸ä½æ°æ°ç»æ¿å°ä¸é´ä½ç½®çæ°ï¼ç¬¬mArr.length / 2å°çæ°ï¼ï¼ç¸åçé®é¢
// è¿åå¼å°±æ¯æä»¬éè¦çååå¼m
// marr(0, marr.len - 1, mArr.length / 2 )
return bfprt(mArr, 0, mArr.length - 1, mArr.length / 2);
}
public static int getMedian(int[] arr, int L, int R) {
insertionSort(arr, L, R);
return arr[(L + R) / 2];
}
// ç±äºç¡®å®æ¯5ä¸ªæ°æåºï¼æä»¬éæ©ä¸ä¸ªå¸¸æ°é¡¹æä½çæåº-æå
¥æåº
public static void insertionSort(int[] arr, int L, int R) {
for (int i = L + 1; i <= R; i++) {
for (int j = i - 1; j >= L && arr[j] > arr[j + 1]; j--) {
swap(arr, j, j + 1);
}
}
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) (Math.random() * maxSize) + 1];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * (maxValue + 1));
}
return arr;
}
public static void main(String[] args) {
int testTime = 1000000;
int maxSize = 100;
int maxValue = 100;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = generateRandomArray(maxSize, maxValue);
int k = (int) (Math.random() * arr.length) + 1;
int ans1 = minKth1(arr, k);
int ans2 = minKth2(arr, k);
int ans3 = minKth3(arr, k);
if (ans1 != ans2 || ans2 != ans3) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}
```
2.2 bfprtç®æ³åºç¨
é¢ç®ï¼æ±ä¸ä¸ªæ°ç»ä¸ï¼æ¿åºæææ¯ç¬¬kå°çæ°è¿å°çæ°
å¯ä»¥éè¿bfprtæ¿å°ç¬¬kå°çæ°ï¼å坹忰ç»éåä¸éï¼å°äºè¯¥æ°çæ¿åºæ¥ï¼ä¸è¶³kä½çï¼è¡¥ä¸ç¬¬kå°çæ°
> 对äºè¿ç±»é®é¢ï¼ç¬è¯çæ¶åæå¥½éæ©éæºmï¼è¿è¡partionãè䏿¯éæ©bfprtãbfprtç常æ°é¡¹é«ãé¢è¯çæ¶åå¯ä»¥éæ©bfprtç®æ³