1. 程式人生 > >MyCat分片演算法學習

MyCat分片演算法學習

1 分片列舉

1.1 官方文件

通過在配置檔案中配置可能的列舉id,自己配置分片。
這種規則適用於特定的場景,比如有些業務需要按照省份或區縣來做儲存,而全國的省份區縣固定的,這類業務使用這一規則。配置如下

<tableRule name="sharding-by-intfile">
    <rule>
        <columns>user_id</coulumns>
        <algorithm>hash-int</algorithm>
    </rule>
</tableRule
>
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"> <property name="mapFile">partition-hash-int.txt</property> <property name="type">0</property> <property name="defaultNode">0</property> </function>

partition-hash-int.txt配置:

10000=0
10010=1
DEFAULT_NODE=1

上面columns標識將要分片的表字段,algorithm分片函式。
其中分片函式配置中,mapFile標識配置檔名稱,type預設值為0,0標識Integer,非零標識String,所有的節點配置都是從0開始。

defaultNode預設節點:小於0表示不設定預設節點,大於等於0表示設定預設節點
預設節點的作用:列舉分片時,如果碰到不識別的列舉值,就讓它路由到預設節點
如果不配置預設節點,碰到不識別的列舉值就會報錯

2 固定分片hash演算法

2.1 官方文件

本條規則類似於十進位制的求模運算,區別在於是二進位制的操作,是取id的二進位制低10位(why?)


此演算法的有點在於,如果按照10進製取模運算,在連續插入1-10時他們會把分到1-10個分片,增大了插入的事務控制難度,而此演算法根據二進位制則可能會分到連續的分片,減少事務控制難度

<tableRule name="rule1">
    <rule>
       <columns>user_id</columns>
       <algorithm>func1</algorithm>
    </rule>
</tableRule>

<function name="fuc1" class="org.opencloudb.route.function.PartitionByLong">
    <property name="partitionCount">2,1</property>
    <property name="partitionLength">256,512</property>
</function>

配置說明:
partitionCount分片個數列表,partitionLength分片範圍列表
分割槽長度:預設為最大1024,即最大支援1024分割槽
1024 = sum((count[i]*length[i])). count 和 length 兩個向量的點積恆等於 1024

2.2 個人筆記

即,按照上文的例子來說,將一個表分為1024塊,前兩份分別拿走256塊,第三份拿走512塊。
意義不明,使用string欄位分片時,根據配置的分片規則,只和最後一個字母和倒數第二個字母的部分有關。
只能作用在純數字的列上。好處可以理解,似乎只能適用在id之類的欄位上。如文件中所說,適合在連續插入的時候使用。
這種分片方法適用在什麼地方依舊有待研究

3 範圍約定

3.1 官方文件

此分片適用於提前規劃好分片欄位某個範圍屬於哪個分片
start <= range <= end.
range start-end, data node index
K=1000, M=10000.

<tableRule name="auto-sharding-long">
    <rule>
        <columns>user_id</columns>
        <algorithm>rang-long</algorithm>
    </rule>
</tableRule>
<function name="rang-long" class="org.opencloudb.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txt</property>
    <property name="defaultNode">0</property>
</function>
    0-500M=0
    500M-1000M=1
    1000M-1500M=2

3.2 個人筆記

將數值型別臨近的資料分在一起。如果能獲得某條資料具體在哪個分片表中,就可以簡化全域性排序(需要去查檢視
**分片依據的數值改變超過分片界限後是否會重新分佈?(需驗證)**

分片依據的那一列資料無法改變,用處瞬間變小。

4 取模

4.1 官方文件

此規則為對分片欄位求模運算。

<tableRule name="mod-long">
    <rule>
        <columns>user_id</columns>
        <algorithm>mod-long</algorithm>
    </rule>
</tableRule>
<funciton name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
    <property name="count">3</property>
</funciton>

此種配置非常明確地根據id進行十進位制取模運算,相比固定分片hash,這種方法在批量插入時可能存在批量插入單事物插入多資料分片,增大失誤一致性難度。

4.2 個人筆記

缺點有了,優點在哪兒??

5 按日期(天)分片

5.1 官方文件

<tableRule name="sharding-by-date">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-date</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-date" class="org.opencloudb.route.function.PartitionByDate">
    <property name="dateFormat">yyyy-MM-dd</property>121
    <property name="sBeginDate">2014-01-01</property>
    <property name="sEndDate">2014-01-02</property>
    <property name="sPartionDay">10</property>
</function>

如果配置了 sEndDate 則代表資料達到了這個日期的分片後後迴圈從開始分片插入。

5.2 個人筆記

啥啥啥???文件說的不明不白的,需要具體試一下是怎麼分片的。

6 取模範圍約束

6.1 官方文件

此種規則是取模運算與範圍約束的結合,主要為了後續資料遷移做準備,即可以自主決定取模後資料的節點
分佈。
“`html


user_id
sharding-by-pattern



256
2
partition-pattern.txt


```text
partition-pattern.txt




<div class="se-preview-section-delimiter"></div>

# id partition range start-end ,data node index




<div class="se-preview-section-delimiter"></div>

###### first host configuration
1-32=0
33-64=1122
65-96=2
97-128=3




<div class="se-preview-section-delimiter"></div>

######## second host configuration
129-160=4
161-192=5
193-224=6
225-256=7
0-0=7




<div class="se-preview-section-delimiter"></div>

上面 columns 標識將要分片的表字段,algorithm 分片函式,patternValue 即求模基數,defaoultNode
預設節點,如果配置了預設,則不會按照求模運算

配置檔案中,1-32 即代表 id%256 後分布的範圍,如果在 1-32 則在分割槽 1,其他類推,如果 id 非資料,則
會分配在 defaoultNode 預設節點

6.2 個人筆記

取模後再範圍約束可以解決需要根據分片欄位的值來設計分片的問題,如果分片用的欄位是類似銷售額之類的內容,如果銷售額增加超過了之前設定的上限,那麼範圍約束演算法會報錯或者將資料全都放到預設分片中。這個演算法則不會。
所謂的“為了後續資料遷移做準備”是什麼意思?為什麼這樣的分片可以做到這一點?

7 擷取數字做 hash 求模範圍約束

7.1 官方文件

此種規則類似於取模範圍約束,此規則支援資料符號字母取模。

<tableRule name="sharding-by-prefixpattern">
    <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-prefixpattern</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-pattern" class="org.opencloudb.route.function.PartitionByPrefixPattern">
    <property name="patternValue">256</property>
    <property name="prefixLength">5</property>
    <property name="mapFile">partition-pattern.txt</property>
</function>




<div class="se-preview-section-delimiter"></div>
partition-pattern.txt
# range start-end ,data node index
# ASCII
# 8-57=0-9 阿拉伯數字123
# 64、 [email protected]、 A-Z
# 97-122=a-z
###### first host configuration
1-4=0
5-8=1
9-12=2
13-16=3
###### second host configuration
17-20=4
21-24=5
25-28=6
29-32=7
0-0=7

上面 columns 標識將要分片的表字段,algorithm 分片函式,patternValue 即求模基數,prefixLength
ASCII 擷取的位數

此種方式類似方式 6 只不過採取的是將列種獲取前 prefixLength 位列所有 ASCII 碼的和進行求模
sum%patternValue ,獲取的值,在範圍內的分片數。

8 應用指定

8.1 官方文件

此規則是在執行階段有應用自主決定路由到那個分片。

<tableRule name="sharding-by-substring">
    <rule>
      <columns>user_id</columns>
        <algorithm>sharding-by-substring</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-substring" class="org.opencloudb.route.function.PartitionDirectBySubString">
    <property name="startIndex">0</property><!-- zero-based -->124
    <property name="size">2</property>
    <property name="partitionCount">8</property>
    <property name="defaultPartition">0</property>
</function>

上面 columns 標識將要分片的表字段,algorithm 分片函式,此方法為直接根據字元子串(必須是數字)計算分割槽號(由應用傳遞引數,顯式指定分割槽號)。
例如 id=05-100000002,在此配置中代表根據 id 中從 startIndex=0,開始,擷取 siz=2 位數字即 05,05 就是獲取的分割槽,如果沒傳預設分配到 defaultPartition

9 擷取數字hash解析

9.1 官方文件

此規則是擷取字串中的 int 數值 hash 分片。

<tableRule name="sharding-by-stringhash">
    <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-stringhash</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-stringhash" class="org.opencloudb.route.function.PartitionByString">
    <property name="partitionLength">512</property><!-- zero-based -->
    <property name="partitionCount">2</property>
    <property name="hashSlice">0:2</property>
</function>
/**
* “2” -> (0,2)
* “1:2” -> (1,2)
* “1:” -> (1,0)
* “-1:” -> (-1,0)
* “:-1” -> (0,-1)125
* “:” -> (0,0)
*/

10 一致性hash

10.1 官方文件

一致性 hash 預算有效解決了分散式資料的擴容問題。

<tableRule name="sharding-by-murmur">
    <rule>
    <columns>user_id</columns>
    <algorithm>murmur</algorithm>
</rule>
</tableRule>
<function name="murmur" class="org.opencloudb.route.function.PartitionByMurmurHash">
    <property name="seed">0</property><!-- 預設是 0-->
    <property name="count">2</property><!-- 要分片的資料庫節點數量,必須指定,否則沒法分片-->
    <property name="virtualBucketTimes">160</property><!-- 一個實際的資料庫節點被對映為這麼多虛擬節點,預設是 160 倍,也就是虛擬節點數是物理節點數的 160 倍-->
<!--
<property name="weightMapFile">weightMapFile</property>
節點的權重,沒有指定權重的節點預設是 1。以 properties 檔案的格式填寫,以從 0 開始到 count-1 的整數值也就是節點索引為 key,以節點權重值為值。所有權重值必須是正整數,否則以 1 代替
-->
<!--
<property name="bucketMapPath">/etc/mycat/bucketMapPath</property>
用於測試時觀察各物理節點與虛擬節點的分佈情況,如果指定了這個屬性,會把虛擬節點的 murmur hash 值與物理節點的對映按行輸出到這個檔案,沒有預設值,如果不指定,就不會輸出任何東西
-->
</function>

假設有10個分片節點,1000萬的資料量,主鍵從100萬開始自增。
執行PartitionByMurmurHash的main方法,按上述假設會得到以下結果

index bucket ratio
 0 1001836 0.1001836
 1 1038892 0.1038892
 2 927886 0.0927886
 3 972728 0.0972728
 4 1086100 0.10861
 5 908616 0.0908616
 6 1024269 0.1024269
 7 1018029 0.1018029
 8 995581 0.0995581
 9 1026063 0.1026063

第一列是分片節點的編號,第二列是hash到每個節點的資料量,第三列是每個hash到每個節點的資料量與總資料量的比值。第三列的和是1.0,第十五列的和是10000000。 如果資料量相當少,會發現一致性雜湊的分佈不夠均勻,而只要資料量在10000以上一致性雜湊的分佈比率就能保持在0.1左右,資料越多分佈越均勻,每個節點的資料量越接近。
現在假設增加二個新節點,對0號節點執行rehash,會出現以下結果

 index bucket ratio
 0 853804 0.8522392886660092
 1 0 0.0
 2 0 0.0
 3 0 0.0
 4 0 0.0
 5 0 0.0
 6 0 0.0
 7 0 0.0
 8 0 0.0
 9 0 0.0
 10 70075 0.06994657808264028
 11 77957 0.07781413325135052

第一第二列的意義與上一組列表一樣,第三列是hash到當前節點上的資料量與原0號節點總資料量的比值。 從以上列表可以看到,原0號節點有1001836資料,rehash之後大部分資料仍然hash到0號上面,少量資料hash到了10、11號兩個新節點,其它舊節點沒有得到原來0號上的資料。其實不管增加多少節點,資料的rehash結果都會呈現這個規律:已有節點的資料發生rehash時只有兩個可能的去處,要麼是rehash之前的節點,要麼是新增加的節點,這也是一致性雜湊的意義所在。
採用這種該片方式,可以保證資料在rehash時儘可能的少遷移資料。

10.2 個人筆記

如何rehash??

11 按月單小時拆分

11.1 官方筆記

此規則是單月內按照小時拆分,最小粒度是小時,可以一天最多 24 個分片,最少 1 個分片,一個月完後下月
從頭開始迴圈。
每個月月尾,需要手工清理資料。

<tableRule name="sharding-by-hour">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-hour</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-hour" class="org.opencloudb.route.function.LatestMonthPartion">
    <property name="splitOneDay">24</property>
</function>

splitOneDay : 一天切分的分片數

LatestMonthPartion partion = new LatestMonthPartion();
partion.setSplitOneDay(24);
Integer val = partion.calculate("2015020100");
assertTrue(val == 0);
val = partion.calculate("2015020216");
assertTrue(val == 40);
val = partion.calculate("2015022823");
assertTrue(val == 27 * 24 + 23);
Integer[] span = partion.calculateRange("2015020100", "2015022823");
assertTrue(span.length == 27 * 24 + 23 + 1);
assertTrue(span[0] == 0 && span[span.length - 1] == 27 * 24 + 23);
span = partion.calculateRange("2015020100", "2015020123");127
assertTrue(span.length == 24);
assertTrue(span[0] == 0 && span[span.length - 1] == 23);

12 範圍求模分片

12.1 官方文件

先進行範圍分片計算出分片組,組內再求模
優點可以避免擴容時的資料遷移,又可以一定程度上避免範圍分片的熱點問題
綜合了範圍分片和求模分片的優點,分片組內使用求模可以保證組內資料比較均勻,分片組之間是範圍分片
可以兼顧範圍查詢。
最好事先規劃好分片的數量,資料擴容時按分片組擴容,則原有分片組的資料不需要遷移。由於分片組內資料比較均勻,所以分片組內可以避免熱點資料問題。

<tableRule name="auto-sharding-rang-mod">
    <rule>
        <columns>id</columns>
        <algorithm>rang-mod</algorithm>
    </rule>
</tableRule>
<function name="rang-mod" class="org.opencloudb.route.function.PartitionByRangeMod">
    <property name="mapFile">partition-range-mod.txt</property>
    <property name="defaultNode">21</property>
</function>

上面 columns 標識將要分片的表字段,algorithm 分片函式,
rang-mod 函式中 mapFile 代表配置檔案路徑
defaultNode 超過範圍後的預設節點順序號,節點從 0 開始。
partition-range-mod.txt
range start-end ,data node group size
以下配置一個範圍代表一個分片組,=號後面的數字代表該分片組所擁有的分片的數量。
0-200M=5 //代表有 5 個分片節點
200M1-400M=1
400M1-600M=4
600M1-800M=4
800M1-1000M=6

13 日期範圍hash分片

13.1 官方文件

思想與範圍求模一致,當由於日期在取模會有資料集中問題,所以改成 hash 方法。
先根據日期分組,再根據時間 hash 使得短期內資料分佈的更均勻
優點可以避免擴容時的資料遷移,又可以一定程度上避免範圍分片的熱點問題128
要求日期格式儘量精確些,不然達不到區域性均勻的目的

<tableRule name="rangeDateHash">
    <rule>
        <columns>col_date</columns>
        <algorithm>range-date-hash</algorithm>
    </rule>
</tableRule>
<function name="range-date-hash" class="org.opencloudb.route.function.PartitionByRangeDateHash">
    <property name="sBeginDate">2014-01-01 00:00:00</property>
    <property name="sPartionDay">3</property>
    <property name="dateFormat">yyyy-MM-dd HH:mm:ss</property>
    <property name="groupPartionSize">6</property>
</function>

14 冷熱資料分片

14.1 官方文件

根據日期查詢日誌資料 冷熱資料分佈 ,最近 n 個月的到實時交易庫查詢,超過 n 個月的按照 m 天分片。

<tableRule name="sharding-by-date">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-hotdate</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-hotdate" class="org.opencloudb.route.function.PartitionByHotDate">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sLastDay">10</property>
    <property name="sPartionDay">30</property>
</function>

15 自然月分片

15.1 官方文件

按月份列分割槽 ,每個自然月一個分片,格式 between 操作解析的範例。

<tableRule name="sharding-by-month">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-month</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-month" class="org.opencloudb.route.function.PartitionByMonth">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2014-01-01</property>
</function>
PartitionByMonth partition = new PartitionByMonth();
partition.setDateFormat("yyyy-MM-dd");
partition.setsBeginDate("2014-01-01");
partition.init();
Assert.assertEquals(true, 0 == partition.calculate("2014-01-01"));
Assert.assertEquals(true, 0 == partition.calculate("2014-01-10"));
Assert.assertEquals(true, 0 == partition.calculate("2014-01-31"));
Assert.assertEquals(true, 1 == partition.calculate("2014-02-01"));
Assert.assertEquals(true, 1 == partition.calculate("2014-02-28"));
Assert.assertEquals(true, 2 == partition.calculate("2014-03-1"));
Assert.assertEquals(true, 11 == partition.calculate("2014-12-31"));
Assert.assertEquals(true, 12 == partition.calculate("2015-01-31"));
Assert.assertEquals(true, 23 == partition.calculate("2015-12-31"));

二次開發

開發新的分片規則
建一個新的類,繼承AbstractPartitionAlgorithm實現RuleAlgorithm。重寫public void init()和public Integer calculate(String columnValue)。
init根據rule.xml指定的分片初始化引數初始化分片規則,calculate(String)接收分片欄位的字串形式計算記錄應該儲存的節點。

總筆記

Todo:
- 試驗下固定分片Hash
- 看下範圍約定的原始碼,主要是怎麼轉換二進位制的。測試下具體分片效果
- 去看看日期分片的原始碼
- 試一下日期分片那個sEndDate的用處
- 為何一致性hash預算能解決擴容問題?
- 單月按小時分片裡面的需要手工清理資料何解?清理到哪兒去?

Note:
- 變更規則後需要重啟mycat才能生效,或者在mysql中使用”
- 使用Insert的時候需要指定ColumnList,不能隱藏
- 固定分片Hash演算法所對應的列只支援數字
- 無法對分片演算法使用的行進行Update
- 文件中寫的演算法class路徑與實際路徑不一致,新的路徑是“io.mycat.”開頭的
- 按照日期分片不需要顯式地定義分片數,具體分片數量由sBeginDate,sEndDate和sPartionDay三者決定,前兩者決定了總天數,第三者決定了每x天換一個分片。
sEndDate到達後會從頭開始分配。

相關推薦

MyCat分片演算法學習

1 分片列舉 1.1 官方文件 通過在配置檔案中配置可能的列舉id,自己配置分片。 這種規則適用於特定的場景,比如有些業務需要按照省份或區縣來做儲存,而全國的省份區縣固定的,這類業務使用這一規則。配置如下 <table

Mycat學習實戰-Mycat分片

mysql mycat 分片 詳情:http://blog.csdn.net/ygqygq2/article/details/78390985本文出自 “ygqygq2” 博客,請務必保留此出處http://ygqygq2.blog.51cto.com/1009869/1981540Mycat學習

mycat分片規則

ext 擴容 難題 begin att func 跨庫 -a 方法 配置:schema文件rule字段,rule文件name字段 (1)分片枚舉:sharding-by-intfile (2)主鍵範圍:auto-sharding-long (3)一致性hash:shardi

mysql 第二十篇文章~mycat 分片規則的初步講解

場景 fault XML 配置文件 理解 fun int 完全 文本 一 簡介:今天咱們來聊聊分片規則的初步理解 二 前沿:mycat的分片規則是十分豐富的,此外還可以根據java進行擴展 三 文件:rule.xml 四 具體分片規則: <tableRule

mycat分片規則之分片枚舉(sharding-by-intinfile)

別人 ade 員工信息 cat oracle server register 正常 cor 剛開始看教程資料的時候,看教程文檔感覺模糊,完全沒明白分片枚舉是個什麽樣的概念。於是網上搜素別人做的 案例來看,終於讓我搜索到一份完整的測試案例,見如下地址: https://w

RocketMQ Consumer 負載均衡演算法學習 -- AllocateMessageQueueAveragelyByCircle

首先, RocketMQ Consumer 的負載均衡指的是把Topic 下的所有MessageQueue 分配到不同的 Consumer 中,所以Message Queue , Consumer 的數量,某個Consumer 的位置 會影響到負載均衡。 這邊介紹下環形平均分配的演算法:

[學習筆記] Berlekamp-Massey演算法 - 學習筆記

重新實現了一個看上去就像是對的的東西。 推薦:傳送門 講的很清楚了,不多贅述。 #include<bits/stdc++.h> #define gc getchar() #define rep(i,a,b) for(int i=a;i<=b;i++) #define R

基本演算法學習(一)—— 排序

排序 一、氣泡排序   演算法思想: 在每一次對比排序中將大的數放在後面,整個排下來後,就變成有序的數列了   演算法實現:       1.(範圍為整個陣列),從前向後兩兩比較,如果前面比後面大就交換位置。第一遍後就將大的放在了最後       2.(縮小範圍),從頭再次重

演算法學習——支援向量機SVM

SVM現在的公式推導很多,都是現成的,而且寫的也很好,我會提供相關資源,這篇博文主要從思想理解的方面做一個簡單介紹。 1、SVM 是如何工作的? 支援向量機的基礎概念可以通過一個簡單的例子來解釋。讓我們想象兩個類別:紅色和藍色,我們的資料有兩個特徵:x 和 y。我們想要一個分類器,給定一

演算法學習——邏輯迴歸(Logistic Regression)

1.Logistic Regression 1.1什麼是迴歸? 英文單詞Regression翻譯成中文“迴歸”,那什麼是迴歸呢?事實上,在Logistic迴歸出現以前,人們最先引入的是線性迴歸。瞭解二者之間的來龍去脈將幫助你更深刻地認識Logistic迴歸。 迴歸一詞最早由英國科學家

演算法學習——線性迴歸

1.線性迴歸模型表示 一元線性迴歸表示: 多元線性迴歸表示: 矩陣表示:,其中                             &n

蟻群演算法學習

** 蟻群演算法的基本原理(簡單概括): ** 剛開始螞蟻按照同等概率選擇各條路徑。 螞蟻在經過的路徑下留下資訊素。 短的路徑螞蟻會率先找到食物源,因此資訊素濃度偏大。 由於資訊素的揮發,較長路徑上的資訊素逐漸消失 特點:正反饋;不容易陷入區域

演算法學習——遞推之水手分椰子

演算法描述 五個水手來到一個島上,採了一堆椰子後,因為疲勞都睡著了。一段時間後,第一個水手醒來,悄悄地將椰子等分成五份,多出一個椰子,便給了旁邊的猴子,然後自己藏起一份,再將剩下的椰子重新合在一起,繼續睡覺。不久,第二名水手醒來,同樣將椰子了等分成五份,恰好也多出一個,也給了猴子。然而自己也藏起一份,

演算法學習——回溯之伯努利裝錯信封問題

演算法描述 某人給6個朋友每個人都寫了一封信,同時寫了這6個朋友地址的信封,有多少種投放信箋的方法,使得每封信與信封上的收信人都不相符? 演算法思路 6封信可能出現的結果: 所有的信都是在對應的信封中,也就是所有的信都放對了信封,這種情況只有一種 部分信放錯了信封

演算法學習——遞推演算法之擺動數列

演算法描述 已知遞推數列: a(1)=1 a(2i)=a(i)+1 a(2i+1)=a(i)+a(i+1) (i為正整數) 求該數列的第n項,以及前n項中的最大值為多少,其n為多少? 演算法思路 採用遞推的方法,使用一維陣列,從2開始遞推,

演算法學習——中國大學MOOC-陳越、何欽銘-資料結構-起步能力自測題——java程式碼實現

自測-1 列印沙漏 (20 point(s)) 本題要求你寫個程式把給定的符號列印成沙漏的形狀。例如給定17個“*”,要求按下列格式列印 ***** *** * *** ***** 所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大

演算法學習——尋找字串中的最長迴文子串

文章轉載自公眾號《網際網路偵查》 /** * @author xiaoshi on 2018/9/24. * Happy Mid-Autumn Festival */ public class PlalindromeString { // 判斷一個字串是否迴文,演算法中用

演算法學習——最大子列和問題

參考視訊: 中國大學mooc——浙江大學——資料結構——陳越、何欽銘 問題描述: 求取陣列中最大連續子序列和,例如給定陣列為A={1, 3, -2, 4, -5}, 則最大連續子序列和為6,即1+3+(-2)+ 4 = 6。 演算法一 int MaxSubseqSu

演算法學習——Map的四種遍歷方法詳解

參考文獻:Java中如何遍歷Map物件的4種方法 java中的所有map都實現了Map介面,以下方法適用於任何map實現(HashMap, TreeMap, LinkedHashMap, Hashtable, and so on) 方法一 在for-each迴圈中使用entr

演算法學習——卡特蘭數

聯賽前複習一點東西吧。。。 計算公式:   \[h_{n} = h_{0} \cdot h_{n - 1} + h_{1} \cdot h_{h - 2} + ... + h_{n - 1} \cdot h_{0}\]   \[h_{n} = h_{n - 1} \cdot (4n - 2) / (n +