Prolog学习:数独和八皇后问题

时间:2023-01-15 13:59:13

上一篇简单介绍了下Prolog的一些基本概念,今天我们来利用这些基本概念解决两个问题:数独八皇后问题。

数独

数独是一个很经典的游戏:

玩家需要根据n×n盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-n,不重复。

Prolog学习:数独和八皇后问题

当然数独的阶有很多,9×9是最常见的,我们就以它做例子。在用Prolog解决之前先想想如果我们用C#或Java来做或怎么做?无非就是数据结构加算法,我们先得用一个数据结构表示数独,然后我们要在这个数据结构上“施加”算法进行求解。采用Prolog的第一步是相同的,我们得找一个数据结构表示数独,毫无疑问在Prolog中我们只能选择列表或元组,这里列表是更好的选择,因为列表可以进行[Head|Tail]解析,后面你就知道为什么了。我们像下面这样表示一个数独:

[_, , _, , , , _, _, _,
, _, , _, _, _, , _, _,
_, , _, , _, _, _, , _,
, _, , _, , _, _, _, ,
, _, _, , _, , _, _, ,
, _, _, _, , _, , _, ,
_, , _, _, _, , _, , _,
_, _, , _, _, _, , _, ,
_, _, _, , , , _, , _]

“_”代表未知的数字,需要玩家填空的地方。

接下来的步骤跟命令式语言就截然不同了,我们不是描述算法,而是要描述数独这个游戏的规则:

  1. 给定玩家一个9×9的盘面,玩家填充完所有的空格后最终的解仍然是这个9×9的盘面;
  2. 填充完空格后,每一个空格内的数字均在1~9之内;
  3. 填充完空格后,每一行9个数字各不相同;
  4. 填充完空格后,每一列9个数字各不相同;
  5. 填充完空格后,每一个宫格内的数字各不相同。

Ok,这就是整个游戏的规则。你可能觉得第一条规则没什么用,实际上第一条规则定义了“解”的形式,就像在C#中我们确定了方法的签名一样:

sudoku(Puzzle,Solution):- Solution = Puzzle.

事实上这个规则已经可以工作了:

| ?- sudoku([,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,],Solution). Solution = [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,......

当然这只是第一步,这个规则对于输入的数独形式没有任何限制,事实上可以是任意的列表,Prolog都返回yes:

| ?- sudoku([,,],Solution).

Solution = [,,]

yes

我们需要规定下数独的形式:

sudoku(Puzzle,Solution):-
Solution = Puzzle,
Puzzle = [S11,S12,S13,S14,S15,S16,S17,S18,S19,
S21,S22,S23,S24,S25,S26,S27,S28,S29,
S31,S32,S33,S34,S35,S36,S37,S38,S39,
S41,S42,S43,S44,S45,S46,S47,S48,S49,
S51,S52,S53,S54,S55,S56,S57,S58,S59,
S61,S62,S63,S64,S65,S66,S67,S68,S69,
S71,S72,S73,S74,S75,S76,S77,S78,S79,
S81,S82,S83,S84,S85,S86,S87,S88,S89,
S91,S92,S93,S94,S95,S96,S97,S98,S99].
| ?- sudoku([,,],Solution).

no

我们接着看第二条规则:“填充完空格后,每一个空格内的数字均在1~9之内” 。上一篇文章中我们介绍了Prolog中有一个内置谓词叫fd_domain,这时候就可以派上用场了:

sudoku(Puzzle,Solution):-
Solution = Puzzle,
Puzzle = [S11,S12,S13,S14,S15,S16,S17,S18,S19,
S21,S22,S23,S24,S25,S26,S27,S28,S29,
S31,S32,S33,S34,S35,S36,S37,S38,S39,
S41,S42,S43,S44,S45,S46,S47,S48,S49,
S51,S52,S53,S54,S55,S56,S57,S58,S59,
S61,S62,S63,S64,S65,S66,S67,S68,S69,
S71,S72,S73,S74,S75,S76,S77,S78,S79,
S81,S82,S83,S84,S85,S86,S87,S88,S89,
S91,S92,S93,S94,S95,S96,S97,S98,S99],
fd_domain(Puzzle,1,9).

好了现在我们只能输入9×9并且每个每个位置上只能是1~9之间的数的列表了。

好了,现在到整个游戏的关键规则,事实上2,3,4这三个规则才决定了数独的难度,1,2只不过是基础,我们来统一考虑这三个问题。这里其实比想象的简单多了。我们首先要做的就是需要定义出来宫格

Row1 = [S11,S12,S13,S14,S15,S16,S17,S18,S19],
Row2 = [S21,S22,S23,S24,S25,S26,S27,S28,S29],
Row3 = [S31,S32,S33,S34,S35,S36,S37,S38,S39],
Row4 = [S41,S42,S43,S44,S45,S46,S47,S48,S49],
Row5 = [S51,S52,S53,S54,S55,S56,S57,S58,S59],
Row6 = [S61,S62,S63,S64,S65,S66,S67,S68,S69],
Row7 = [S71,S72,S73,S74,S75,S76,S77,S78,S79],
Row8 = [S81,S82,S83,S84,S85,S86,S87,S88,S89],
Row9 = [S91,S92,S93,S94,S95,S96,S97,S98,S99], Col1 = [S11,S21,S31,S41,S51,S61,S71,S81,S91],
Col2 = [S12,S22,S32,S42,S52,S62,S72,S82,S92],
Col3 = [S13,S23,S33,S43,S53,S63,S73,S83,S93],
Col4 = [S14,S24,S34,S44,S54,S64,S74,S84,S94],
Col5 = [S15,S25,S35,S45,S55,S65,S75,S85,S95],
Col6 = [S16,S26,S36,S46,S56,S66,S76,S86,S96],
Col7 = [S17,S27,S37,S47,S57,S67,S77,S87,S97],
Col8 = [S18,S28,S38,S48,S58,S68,S78,S88,S98],
Col9 = [S19,S29,S39,S49,S59,S69,S79,S89,S99], Square1 = [S11,S12,S13,S21,S22,S23,S31,S32,S33],
Square2 = [S14,S15,S16,S24,S25,S26,S34,S35,S36],
Square3 = [S17,S18,S19,S27,S28,S29,S37,S38,S39],
Square4 = [S41,S42,S43,S51,S52,S53,S61,S62,S63],
Square5 = [S44,S45,S46,S54,S55,S56,S64,S65,S66],
Square6 = [S47,S48,S49,S57,S58,S59,S67,S68,S69],
Square7 = [S71,S72,S73,S81,S82,S83,S91,S92,S93],
Square8 = [S74,S75,S76,S84,S85,S86,S94,S95,S96],
Square9 = [S77,S78,S79,S87,S88,S89,S97,S98,S99],

上一篇文章中我还提到一个谓词叫fd_all_different:检查列表中是否有重复元素,接下来我们只要证明每一列,每一行,每一个宫格列表内没有重复元素就可以了:

fd_all_different(Row1),
fd_all_different(Row2),
……
fd_all_different(Col1),
fd_all_different(Col2),
……
fd_all_different(Square1),
fd_all_different(Square2),
……

其实到此这个解数独的程序已经结束了,不过最后这几行代码太土了,我们可以采用用递归“优化”下,像下面这样:

valid([]).
valid([Head|Tail]):-
fd_all_different(Head),
valid(Tail).
valid([Row1,Row2,Row3,Row4,Row5,Row6,Row7,Row8,Row9,
Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,
Square1,Square2,Square3,Square4,Square5,Square6,Square7,Square8,Square9]).

不管你信不信,我们已经搞定了,最终完整的代码如下:

valid([]).
valid([Head|Tail]):-
fd_all_different(Head),
valid(Tail).
sudoku(Puzzle,Solution):-
Solution = Puzzle,
Puzzle = [S11,S12,S13,S14,S15,S16,S17,S18,S19,
S21,S22,S23,S24,S25,S26,S27,S28,S29,
S31,S32,S33,S34,S35,S36,S37,S38,S39,
S41,S42,S43,S44,S45,S46,S47,S48,S49,
S51,S52,S53,S54,S55,S56,S57,S58,S59,
S61,S62,S63,S64,S65,S66,S67,S68,S69,
S71,S72,S73,S74,S75,S76,S77,S78,S79,
S81,S82,S83,S84,S85,S86,S87,S88,S89,
S91,S92,S93,S94,S95,S96,S97,S98,S99],
fd_domain(Puzzle,,), Row1 = [S11,S12,S13,S14,S15,S16,S17,S18,S19],
Row2 = [S21,S22,S23,S24,S25,S26,S27,S28,S29],
Row3 = [S31,S32,S33,S34,S35,S36,S37,S38,S39],
Row4 = [S41,S42,S43,S44,S45,S46,S47,S48,S49],
Row5 = [S51,S52,S53,S54,S55,S56,S57,S58,S59],
Row6 = [S61,S62,S63,S64,S65,S66,S67,S68,S69],
Row7 = [S71,S72,S73,S74,S75,S76,S77,S78,S79],
Row8 = [S81,S82,S83,S84,S85,S86,S87,S88,S89],
Row9 = [S91,S92,S93,S94,S95,S96,S97,S98,S99], Col1 = [S11,S21,S31,S41,S51,S61,S71,S81,S91],
Col2 = [S12,S22,S32,S42,S52,S62,S72,S82,S92],
Col3 = [S13,S23,S33,S43,S53,S63,S73,S83,S93],
Col4 = [S14,S24,S34,S44,S54,S64,S74,S84,S94],
Col5 = [S15,S25,S35,S45,S55,S65,S75,S85,S95],
Col6 = [S16,S26,S36,S46,S56,S66,S76,S86,S96],
Col7 = [S17,S27,S37,S47,S57,S67,S77,S87,S97],
Col8 = [S18,S28,S38,S48,S58,S68,S78,S88,S98],
Col9 = [S19,S29,S39,S49,S59,S69,S79,S89,S99], Square1 = [S11,S12,S13,S21,S22,S23,S31,S32,S33],
Square2 = [S14,S15,S16,S24,S25,S26,S34,S35,S36],
Square3 = [S17,S18,S19,S27,S28,S29,S37,S38,S39],
Square4 = [S41,S42,S43,S51,S52,S53,S61,S62,S63],
Square5 = [S44,S45,S46,S54,S55,S56,S64,S65,S66],
Square6 = [S47,S48,S49,S57,S58,S59,S67,S68,S69],
Square7 = [S71,S72,S73,S81,S82,S83,S91,S92,S93],
Square8 = [S74,S75,S76,S84,S85,S86,S94,S95,S96],
Square9 = [S77,S78,S79,S87,S88,S89,S97,S98,S99], valid(Row1,Row2,Row3,Row4,Row5,Row6,Row7,Row8,Row9,
Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,
Square1,Square2,Square3,Square4,Square5,Square6,Square7,Square8,Square9).

反正我信了,我们来试试吧,就以上面我从百度上找到的那个图为例:

| ?- sudoku([_, , _, , , , _, _, _,
, _, , _, _, _, , _, _,
_, , _, , _, _, _, , _,
, _, , _, , _, _, _, ,
, _, _, , _, , _, _, ,
, _, _, _, , _, , _, ,
_, , _, _, _, , _, , _,
_, _, , _, _, _, , _, ,
_, _, _, , , , _, , _],Solution). Solution = [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]

美化后的结果是这样的:

[,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,,
,,,,,,,,]

Perfect!

八皇后问题

Ok,有了数独问题作为铺垫,下面看八皇后问题应该就应该没那么难了,请保持用Prolog思考问题的方式,解决后你会发现Prolog真是这方面的“专家”,Let's Go!

八皇后问题也是一个非常经典的问题:

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

Prolog学习:数独和八皇后问题

老套路我们先描述游戏规则。

  1. 每个皇后有一个行号和列号,行号和列号的取值范围在1~8之间;
  2. 一个棋盘上有八个皇后;
  3. 任意两个皇后不可以共享一行;
  4. 任意两个皇后不可以共享一列;
  5. 任意两个皇后不可以在同一个对角线上(左下角->右上角);
  6. 任意两个皇后不可以在同一个对角线上(右下角->左上角)。

在了解规则之后我们梳理一下这个问题,对照上面这个图:

我们给棋盘上每一个位置设定一个坐标(x,y),八个皇后的坐标分别为(x1,y1),(x2,y2)……我们以回溯的角度看问题,假设如图已经得到了最后解,那么这8个坐标满足:x1,x2……各不相同,y1,y2……个不相同,找出(x1,y1),(x2,y2)……中属于对角线1上的和对角线2上的位置,它们坐标应该个不相同。

(1,1),(,),(,),(,),(,),(,),(,),(1,8)
(,),(2,2),(,),(,),(,),(,),(2,7),(,)
(,),(,),(3,3),(,),(,),(3,6),(,),(,)
(,),(,),(,),(4,4),(4,5),(,),(,),(,)
(,),(,),(,),(5,4),(5,5),(,),(,),(,)
(,),(,),(6,3),(,),(,),(6,6),(,),(,)
(,),(7,2),(,),(,),(,),(,),(7,7),(,)
(8,1),(,),(,),(,),(,),(,),(,),(8,8)

所以整个问题的难点在于给定类似下面这样一个列表,我们需要找出其中的所有的行号,列号,和在对角线上的坐标:

[(,),(,),(,),(,),(,),(4,4),(4,5),(5,4)]

找出行号和列号稍微简单点,这里直接给出答案,大家也可以自己思考下:

rows([],[]).
rows([(Row,_)|QueensTail],[Row|RowsTail]):-
rows(QueensTail,RowsTail).
cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-
cols(QueensTail,ColsTail).

把上面的列表代进去简单验证下:

| ?- rows([(,),(,),(,),(,),(,),(,),(,),(,)],Rows).

Rows = [,,,,,,,]

yes
| ?- cols([(,),(,),(,),(,),(,),(,),(,),(,)],Cols).

Cols = [,,,,,,,]

yes

关键是如何验证对角线上的元素,而且两条对角线是不一样的,提醒下因为我们最后会还是会利用fd_all_different这个谓词。

好吧,我们回过头观察下上面那个棋盘的坐标图(注意我标红的地方),有没有发现什么规则呢?

  • 左上角到右下角的对角线上的元素:所有坐标的横坐标-纵坐标都相同,等于0;
  • 左下角到右上角的对角线上的元素:所有坐标的横坐标+纵坐标都相同,等于9;

OK,我们可以定义下面这样两个谓词diags1和diags2:

diags1([],[]).
diags1([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col - Row,
diags1(QueensTail,DiagonalsTail).
diags2([],[]).
diags2([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col + Row,
diags2(QueensTail,DiagonalsTail).

我们可以简单验证下:

| ?- diags1([(,),(,)],Diags1).

Diags1 = [0,0]

yes

| ?- diags2([(4,5),(5,4)],Diags2).


 Diags2 = [9,9]


yes

如果坐标在对角线上,那么抓取到的列表元素都是相等的。

好了,到目前为止我们已经完成了最难的部分,剩下的都是一些验证性工作。我们最终的“程序入口”应该是这样的:

eight_queens([(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4),(X5,Y5),(X6,Y6),(X7,Y7),(X8,Y8)])

我们还需要一些验证性工作:

1.给定列表里的皇后是不是合法的,即横纵坐标都在1~8之内,这用到了我上一篇中提到的member谓词:

valid_queen((Row,Col)):-
Range = [,,,,,,,],
member(Row,Range),member(Col,Range).

2.验证给定的列表是不是八个皇后,这里用到一个length谓词,顾名思义:

length(Board,).

3.需要递归的验证给定的列表中的每个元素是不是“皇后”:

valid_board([]).
valid_board([Head|Tail]):- valid_queen(Head),valid_board(Tail).

Ok,下面就是八皇后问题的答案的完整代码:

valid_queen((Row,Col)):-
Range = [,,,,,,,],
member(Row,Range),member(Col,Range). valid_board([]).
valid_board([Head|Tail]):- valid_queen(Head),valid_board(Tail). rows([],[]).
rows([(Row,_)|QueensTail],[Row|RowsTail]):-
rows(QueensTail,RowsTail). cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-
cols(QueensTail,ColsTail). diags1([],[]).
diags1([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col - Row,
diags1(QueensTail,DiagonalsTail). diags2([],[]).
diags2([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col + Row,
diags2(QueensTail,DiagonalsTail). eight_queens(Board) :-
length(Board,),
valid_board(Board), rows(Board,Rows),
cols(Board,Cols),
diags1(Board,Diags1),
diags2(Board,Diags2), fd_all_different(Rows),
fd_all_different(Cols),
fd_all_different(Diags1),
fd_all_different(Diags2).

没错,答案已经出来,但事实上上面这个程序运行的非常慢,我在我i7的笔记本上的GNU Prolog中执行下面这个问题,半天没有响应:

| ?- eight_queens([(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4),(X5,Y5),(X6,Y6),(X7,Y7),(X8,Y8)]).

其实我们可以对这个问题进行一个简化。我们可以肯定棋盘上八行每行肯定有一个皇后,又因为互不能在一行,因此我们假设八皇后的坐标分别为:(1,A),(2,B),(3,C),(4,D),(5,E),(6,F),(7,G),(8,H)。那么我们可以对上面的代码进行优化,去掉所有对行的操作,优化后代码如下:

valid_queen((Row,Col)):- member(Col,[,,,,,,,]).

valid_board([]).
valid_board([Head|Tail]):- valid_queen(Head),valid_board(Tail). cols([],[]).
cols([(_,Col)|QueensTail],[Col|ColsTail]):-
cols(QueensTail,ColsTail). diags1([],[]).
diags1([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col - Row,
diags1(QueensTail,DiagonalsTail). diags2([],[]).
diags2([(Row,Col)|QueensTail],[Diagonal|DiagonalsTail]):-
Diagonal is Col + Row,
diags2(QueensTail,DiagonalsTail). eight_queens(Board) :-
Board = [(,_),(,_),(,_),(,_),(,_),(,_),(,_),(,_)],
length(Board,),
valid_board(Board), cols(Board,Cols),
diags1(Board,Diags1),
diags2(Board,Diags2), fd_all_different(Cols),
fd_all_different(Diags1),
fd_all_different(Diags2).

然后这样问问题:

eight_queens([(,Y1),(,Y2),(,Y3),(,Y4),(,Y5),(,Y6),(,Y7),(,Y8)]).
| ?- eight_queens([(,Y1),(,Y2),(,Y3),(,Y4),(,Y5),(,Y6),(,Y7),(,Y8)]).

Y1 =
Y2 =
Y3 =
Y4 =
Y5 =
Y6 =
Y7 =
Y8 = ? a Y1 =
Y2 = Y1 =
Y2 =
Y3 =
Y4 =
Y5 =
Y7 =
Y8 = Y1 =
Y2 =
Y3 =
Y4 =
Y5 =
Y6 =
Y7 =
Y8 = Y1 =
Y2 =
Y3 =
Y4 =
Y5 =
Y6 =
Y7 =
Y8 =
……
Y1 =
Y2 =
Y3 =
Y4 =
Y5 =
Y6 =
Y7 =
Y8 = Y1 =
Y2 =
Y3 =
Y4 =
Y5 =
Y6 =
Y7 =
Y8 = ( ms) no

?后跟a可以一次性询问所有答案,可以看到还是相当的慢,这也算是声明式语言的一个劣势吧。

好了,今天介绍的两个问题就到此结束了。问题本身并不是重点,重点是我们思考问题的方式。

最后提供:源代码下载,希望大家可以喜欢Prolog这门小巧简单,功能强大的语言。

Prolog学习:数独和八皇后问题的更多相关文章

  1. Prolog学习:基本概念 and Asp.net与Dojo交互:仪器仪表实现

    Asp.net与Dojo交互:仪器仪表实现 项目中需要用到仪器仪表的界面来显示实时的采集信息值,于是便遍地寻找,参考了fusionchart和anychart之后,发现都是收费的,破解的又没有这些功能 ...

  2. Prolog学习:基本概念

    上一篇对Prolog有了一个感性的认识,今天介绍下Prolog中一些基本概念,想要用Prolog解决一些实际问题之前必须要先了解它们.这些概念在<七周七语言>这本书中都有介绍,我简单提炼汇 ...

  3. Python学习二&lpar;生成器和八皇后算法&rpar;

    看书看到迭代器和生成器了,一般的使用是没什么问题的,不过很多时候并不能用的很习惯 书中例举了经典的八皇后问题,作为一个程序员怎么能够放过做题的机会呢,于是乎先自己来一遍,于是有了下面这个ugly的代码 ...

  4. 带你轻而易举的学习python——八皇后问题

    首先我们来看一下这个著名的八皇后问题 八皇后问题:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 在这个问题提出之后人们又将 ...

  5. 算法学习 八皇后问题的递归实现 java版 回溯思想

    1.问题描述 八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或 ...

  6. 算法——八皇后问题(eight queen puzzle)之回溯法求解

    八皇后谜题是经典的一个问题,其解法一共有种! 其定义: 首先定义一个8*8的棋盘 我们有八个皇后在手里,目的是把八个都放在棋盘中 位于皇后的水平和垂直方向的棋格不能有其他皇后 位于皇后的斜对角线上的棋 ...

  7. 对八皇后的补充以及自己解决2n皇后问题代码

    有了上次的八皇后的基础.这次准备解决2n皇后的问题,: //问题描述// 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行./ ...

  8. python基础教程总结8——特殊方法,属性,迭代器,生成器,八皇后问题

    1. 重写一般方法和特殊的构造方法 1.1 如果一个方法在B类的一个实例中被调用(或一个属性被访问),但在B类中没有找到该方法,那么会去它的超类A里面找. class A: ... def hello ...

  9. 八皇后问题——列出所有的解,可推至N皇后

    <数据结构>--邓俊辉版本 读书笔记 今天学习了回溯法,有两道习题,一道N皇后,一道迷宫寻径.今天,先解决N皇后问题.由于笔者 擅长java,所以用java重现了八皇后问题. 注意是jav ...

随机推荐

  1. vmware10安装win8x64(亲测)

    首先,创建虚拟机,选择典型 下一步后 弄完后选择“完成”,这下就可以安装了 之后分区,之后选cdrom做启动,之后安装win8到第一分区

  2. C 编译器错误信息中文翻译

    Ambiguous operators need parentheses 不 明确的运算需要用括号括起 Ambiguous symbol ``xxx`` 不明确的符号 Argument list sy ...

  3. 编程内功修炼之数据结构—BTree(三)总结

    BTree必须通过各种编程约束,使得不脱离BTree的本身特性: 1)BTree关键字插入操作:插入过程中,如果节点关键字达到上限,添加分裂约束,从而控制每个节点的关键字数维持在 t-1~2*t-1内 ...

  4. linux下curl编程

    LibCurl是免费的客户端URL传输库,支持FTP,FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE ,LDAP等协议,其主页是http: ...

  5. 008&lowbar;ssl Certificate Pinning

    证书锁定Certificate Pinning技术 在中间人攻击中,攻击主机通常截断客户端和服务器的加密通信.攻击机以自己的证书替代服务器发给客户端的证书.通常,客户端不会验证该证书,直接接受该证书, ...

  6. 【托业】【怪兽】TEST02

    ★ overturn v.推翻 ★ disciplinary adj.纪律的; 训练的; 惩罚的; ★disciplined 有纪律的 ★discipline v.纪律 ★outlook 态度 ★pe ...

  7. CentOS 6&period;5 x64下安装VMware tools

    [root@CentOS6 /]# mount /dev/cdrom /mnt mount: block device /dev/sr0 is write-protected, mounting re ...

  8. 使用MyEclipse开发Java EE应用:用XDoclet创建EJB 2 Session Bean项目(二)

    [MyEclipse最新版下载] 二.创建一个Session EJB – Part 1 MyEclipse中的EJB 2.x开发使用了EJB向导和集成XDoclet支持的组合. 每个EJB由三个基本部 ...

  9. Boost--optional

    #include <vector> #include <deque> #include <iostream> #include <array> #inc ...

  10. MySql(十八):MySql架构设计——高可用设计之 MySQL 监控

    前言: 一个经过高可用可扩展设计的 MySQL 数据库集群,如果没有一个足够精细足够强大的监控系统,同样可能会让之前在高可用设计方面所做的努力功亏一篑.一个系统,无论如何设计如何维护,都无法完全避免出 ...