GIF影象格式(二)——基礎演算法(下)
last_code = -1;
current_string = ''; // 空字串
while (能夠從Code Stream中取出一個Code: this_code) {
if (last_code==-1) { // first code
把Code對應的string輸出到Char Stream;
} else {
if (this_code在string_table中存在) {
current_string = string(last_code);
current_string += string(this_code)[0]; //this_code對應的string的第一個字元
把current_string插入到string_table的末尾;
把this_code對應的string輸出到Char Stream;
} else {
current_string = string(last_code);
current_string += string(last_code)[0]; //last_code對應的string的第一個字元
把current_string插入到string_table的末尾;
把current_string輸出到Char stream;
}
}
last_code = this_code;
}
這個演算法有幾個地方不好理解,首先就是last_code等於-1的時候,我們的做法就是簡單的把Code對應的字串輸出來,這就有了一個問題:這個Code對應的string一定存在嗎?讓我們仔細想想編碼的過程,第一個Code一定是root的index,因此這個string是一定存在的。第二個問題就是對this_code的處理。我們知道,在初始化string table的時候,它只有root_number個項,隨著編碼的過程,這個table一隻增長,但是仍然可能存在得到了一個code卻發現它在string table種對應的字串還沒有生成的情況。結合編碼過程應該不難理解,如果不存在的話,那麼這個Code也應當比當前的table中的最大的一個index僅僅大一,也就是說,如果我們可以用某種方法得到這個應當加入的項,那麼它就是我們要找得項。第三個問題就是為什麼我們總要在讀出一個Code後就要把一個string插入到string_table中,仍然是參考編碼過程,我們總是在輸出了一個Code的同時生成一個string插入到table中,也就是說,在我們進行解碼的時候,如果要讓string_table和我們編碼時同步,也要在讀入一個Code後生成一個string插入到table中。最後一個問題就是對於“Code在string_table中不存在”這種情況的解決方法。從偽碼中可以看到,如果Code存在,構造current_string和輸出的方式都很好理解,但是如果不存在,似乎很無恥的使用了last_code萊得到current_string,其實仔細聯絡編碼方式可以理解:這種方式是必然的。
第一步仍然是初始化string_table:
-----------------------
index string
00 'A'
01 'B'
02 'C'
-----------------------
第二步開始解碼:
Step last_code this_code exist? current_string Insert output
01 -1 01 - - - 'B'
02 01 03 no string(01)+string(01)[0]=BB 'BB' 'BB'
03 03 02 yes string(03)+string(02)[0]=BBC 'BBC' 'C'
04 02 03 yes string(02)+string(03)[0]=CB 'CB' 'BB'
05 03 00 yes string(03)+string(00)[0]=BBA 'BBA' 'A'
解碼結束,輸出為:BBBCBBA,成功地解為原字串。
我們再看看現在的string_table:
-------------------------
index string
00 'A'
01 'B'
02 'C'
03 'BB'
04 'BBC'
05 'CB'
06 'BBA'
-------------------------
與編碼方式比較一下,是完全一樣的。
相關推薦
GIF影象格式(二)——基礎演算法(下)
initialze_string_table(root_number); last_code = -1;
GIF影象格式(一)——基礎演算法(上)
現在我們看看每一步是怎麼做的:第一步:初始化我們的編碼表。剛才說了,初始化編碼表只需要一個引數:root_number,也就是根項的數目。其實他就是我們要編碼的Char Stream中的字符集的數目。初始化也很簡單:根據一個事先的約定對所有的Char進行排序,然後從零開始對其編上一個index,形成一個ite
基礎演算法(二):Kmeans聚類演算法的基本原理與應用
Kmeans聚類演算法的基本原理與應用 內容說明:主要介紹Kmeans聚類演算法的數學原理,並使用matlab程式設計實現Kmeans的簡單應用,不對之處還望指正。 一、Km
基礎演算法(二)篩法求素數
1.基本思想 把從1開始的、某一範圍內的正整數從小到大順序排列, 1不是素數,首先把它篩掉。剩下的數中選擇最小的數是素數,然後去掉它的倍數。依次類推,直到篩子為空時結束。 2.示例 1 2 3 4
NOIP複賽複習(十一)基礎演算法鞏固與提高
一、倍增演算法: 定義:用f[i][j]表示從i位置出發的2j個位置的資訊綜合(狀態) 一個小小的問題:為什麼是2j而不是3j,5j,…?因為,假設為kj,整個演算法的時間複雜度為(k-1)logk,當k=2時,時間複雜度最小。 這個演算法的三個應用:
Python基礎演算法(持續更新)~~
一: 建立一個包含1-100之間所有素數的列表,排序後列印顯示該列表; 隨後只保留該列表前5個數字,刪除其餘內容並列印輸出相應結果; 再將每個元素值加上100,顯示列表內容;把列表轉化為字串。 思路分析: 1.建立一個空列表,用來儲存1-100之間的素
《組合語言(第3版)(王爽 著)》學習筆記二:基礎知識(2)
1.7 CPU 對儲存器的讀寫 以上講到,儲存器被劃分成多個儲存單元,儲存單元從零開始編號。這些編號可以看作儲存單元在儲存器中的地址。就想一條街,每個房子都有門牌號碼。 CPU 要從記憶體中讀資料,
Java 學習(二)—— 基礎語法(轉)
Java 基礎語法 一個Java程式可以認為是一系列物件的集合,而這些物件通過呼叫彼此的方法來協同工作。下面簡要介紹下類、物件、方法和例項變數的概念。 物件:物件是類的一個例項,有狀態和行為。例如,一條狗是一個物件,它的狀態有:顏色、名字、品種;行為有:搖尾巴、叫、吃等。 類:類是
從零開始學USB(二、基礎知識2)
1.USB相關的硬體 USB裝置,從物理上的邏輯結構來說,包含了主機Host端和裝置Device端。 其中,主機Host端,有對應的硬體的USB的主機控制器Host Controller,而裝置端,連線的是對應的USB裝置。 1.1. USB控制器型別:OHCI,UHCI,
藍橋杯練習系統試題集(二)--基礎練習(含C/C++答案)
藍橋杯練習系統試題集(二)–基礎練習(含C/C++答案) 1 基礎練習 閏年判斷 時間限制:1.0s 記憶體限制:256.0MB 提交此題 錦囊1 錦囊2 問題描述 給定一個年份,判斷這一年是不是閏年。 當以下情況之一滿足時
決策樹(一)——基礎演算法
決策樹 定義 根據wikipedia的定義,決策樹學習方法是一種通過決策樹實現從某幾個特徵屬性(分枝)到目標值(葉節點)的預測模型。 一種實現方法是貪心演算法:資料來源按照屬性測試條件分割為子集,然後在生成的每個子集上遞迴執行遞迴分割過程,直到該節點所有子集具有相同的目標變數。
STL基礎--演算法(不修改資料的演算法)
不修改資料的演算法 count, min and max, compare, linear search, attribute // 演算法中Lambda函式很常用: num = count_if(vec.begin(), vec.end(), [](int x){return x<10;
STL基礎--演算法(修改資料的演算法)
修改元素的演算法 copy, move, transform, swap, fill, replace, remove vector<int> vec = {9,60,70,8,45,87,90}; // 7 items vector<int> vec2 = {0
資料結構--二叉樹--輸出樹中從根到每個葉子節點的路徑(樹遍歷演算法的應用) .
void AllPath(Bitree T, Stack &S)//輸出二叉樹上從根到所有葉子結點的路徑 { if(T) { Push(S,T->data); if(!T->Left&&!T->Right)/
STL基礎--演算法(排序)
STL排序演算法 排序演算法要求隨機訪問迭代器 vector, deque, container array, native array 例子 vector<int> vec = {9,1,10,2,45,3,90,4,9,5,8}; sort(vec.begin()
STL基礎--演算法(已排序資料的演算法,數值演算法)
已排序資料的演算法 Binary search, merge, set operations 每個已排序資料演算法都有一個同名的更一般的形式 vector 1. 二分法搜尋 // 搜尋元素 bool found = binary_search(vec.begin(), vec.end()
基礎演算法(四)---深度優先搜尋(DFS)
深度優先搜尋演算法(Depth-First-Search),是搜尋演算法的一種。 它沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分支。 當節點v的所有邊都己被探尋過,搜尋將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達
Go 的面試基礎演算法(一)
兩個陣列求交集 思路,把兩個數組合併成一個數組,然後通過 hash 表找出陣列中重複的元素 package main import "fmt" func ArrayIntersection(arr []int, arr1 []int)
keras面向小資料集的影象分類(VGG-16基礎上fine-tune)實現(附程式碼)
參考譯文地址:http://keras-cn.readthedocs.io/en/latest/blog/image_classification_using_very_little_data/ 本文作者:Francois Chollet 概述 在本文中,將使用VGG-16模型提供一種面向小資料集(幾百
最短路徑(二)—Dijkstra演算法(通過邊實現鬆弛:鄰接矩陣)
上一節通過Floyd-Warshall演算法寫了多源節點最短路徑問題: 這一節來學習指定一個點(源點)到其餘各個頂點的最短路徑。也叫做“單源最短路徑”Dijkstra。 例如求下圖中1號頂點到2、3、4、5、6號頂點的最短路徑。 用二維陣列e儲存頂點之間邊的關係,初