數據結構字元串存儲
⑴ 字元在計算機中的存儲形式
字元在計算機內存放,應規定相應的代表字元的二進制代碼。代碼的選用要與有關外圍設備的規格取得一致。這些外圍設備包括鍵盤控制台的輸入輸出、列印機的輸出等等。字元作輸入時,要自動轉換為二進制代碼存於機內;輸出時,計算機內二進制代碼自動轉化為字元,兩者的轉換全是靠外圍設備實現的。字元是數據結構中最小的數據存取單位。通常由8個二進制位(一個位元組)來表示一個字元,但也有少數計算機系統採用6個二進制的字元表示形式。一個系統中字元集的大小,完全由該系統自己規定。[1]計算機可用字元一般為128~256個(不包括漢字時),每個字元進入計算機後,都將轉換為8位二進制數。不同的計算機系統和不同的語言,所能使用的字元范圍是不同的。
在 ASCII 編碼中,一個英文字母字元存儲需要1個位元組。在 GB 2312 編碼或 GBK 編碼中,一個漢字字元存儲需要2個位元組。在UTF-8編碼中,一個英文字母字元存儲需要1個位元組,一個漢字字元儲存需要3到4個位元組。在UTF-16編碼中,一個英文字母字元或一個漢字字元存儲都需要2個位元組(Unicode擴展區的一些漢字存儲需要4個位元組)。在UTF-32編碼中,世界上任何字元的存儲都需要4個位元組。[3]
表達
字元是可使用多種不同字元方案或代碼頁來表示的抽象實體。例如,Unicode UTF-16 編碼將字元表示為 16 位整數序列,而 Unicode UTF-8 編碼則將相同的字元表示為 8 位位元組序列。[3]微軟的公共語言運行庫使用 Unicode UTF-16(Unicode 轉換格式,16 位編碼形式)表示字元。
作用
針對微軟公共語言運行庫的應用程序使用編碼將字元表示形式從本機字元方案映射至其他方案。應用程序使用解碼將字元從非本機方案映射至本機方案。
電腦和通訊設備會使用字元編碼的方式來表達字元。意思是會將一個字元指定給某個東西。傳統上,是代表整數量的位元序列,如此,則可透過網路來傳輸,同時亦便於儲存。兩個常用的例子是ASCII和用於統一碼的UTF-8。根據谷歌的統計,UTF-8是最常用於網頁的編碼方式。相較於大部分的字元編碼把字元對應到數字或位元串,摩斯密碼則是使用不定長度的電子脈沖的序列來表現字元
⑵ 數據結構問題 字元串是哪三種存儲方式
字元串的三種存儲方式: (C++)
1. 字元數組
例如
charstr[10];
2. 字元指針
例如
char*str=newchar[10];
2. 字元串類型
例如
stringstr;
⑶ Redis數據結構之string類型和list類型
String是redis最基礎和最常用的數據結構,其值最大能存儲 512MB,可以是簡單字元串、復雜的xml/json的字元串、二進制圖像或者音頻的字元串、以及可以是數字的字元串。String底層使用的是SDS,是Redis的一種基本數據結構,主要是用於存儲字元串和整數。
2.1 set命令 set key value
用於設置給定key的值,如果key存儲了其他值,覆蓋寫入,無視類型。
2.2 get命令 get key
獲取指定key的值,如果key不存在返回nil
2.3 getset命令 get key [value]
該命令用於獲取指定的key的舊值,然後按照新值對key進行賦值。當key中沒有舊值的時候返回nil。
2.4 mget命令 get key1 [key2 keyN]
返回多個key的值,某個key不存在時返回nil
2.5 decr命令 decr key
對key對應的數字做減1操作。如果key不存在,那麼在操作之前,這個key對應的值會被置為0。如果key有一個錯誤類型的value或者是一個不能表示成數字的字元串,就返回錯誤。
2.6 incr命令 incr key
對key對應的數字做減1操作。如果key不存在,那麼在操作之前,這個key對應的值會被置為0。如果key有一個錯誤類型的value或者是一個不能表示成數字的字元串,就返回錯誤。
2.7 append命令 append key value
如果 key 已經存在,並且值為字元串,那麼這個命令會把 value 追加到原來值(value)的結尾。 如果 key 不存在,那麼它將首先創建一個空字元串的key,再執行追加操作,這種情況 APPEND 將類似於 SET 操作。返回append後字元串值(value)的長度。
3.1 SDS動態字元串
struct sdshdr {
unsigned int len;
unsigned int free;
char buf[];
}
其中,buf表示數據空間,用於存儲字元串;len表示buf中已佔用的位元組數;free表示空閑的位元組數。
3.2 新的SDS結構
增加了一個flags來標識類型,用一個位元組(8位)來存儲,前3位表示字元串的類型;剩餘5位,存儲長度小於32的段字元串。
創建 SDS 的大致流程是這樣的:首先根據字元串長度計算得到 type,根據 type 計算頭部所需長度,然後動態分配內存空間。
注意:① 創建空字元串時,SDS_TYPE_5 被強制轉換為 SDS_TYPE_8(原因是創建空字元串後,內容可能會頻繁更新而引發擴容操作,故直接創建為 sdshdr8)
②長度計算有 +1 操作,因為結束符 \0 會佔用一個長度的空間。
③返回的是指向 buf 的指針 s。
4.1 session共享
4.2 計數器(商品瀏覽記錄)
4.3 訪問限速
list類型用來存儲多個有序的字元串,列表當中的每一個字元看做一個元素,一個列表當中可以存儲有一個或者多個元素,redis的list支持存儲2^32次方-1個元素。
Redis可以從兩端push和pop元素,支持讀取指定范圍或者制定下表的元素。list是一種靈活的鏈式結構,可以充當隊列或者棧的角色。
list的元素是有序的,且列表內的元素是可以重復的。
注意:Redis3.2以前,列表底層的編碼是ziplist(壓縮列表)和linkedlist(雙向列表)實現的,因為雙線列表佔用的內存比壓縮列表多,所以當創建新的列表鍵時,列表會優先考慮用壓縮列表,只有在需要的時候才會轉換到雙向列表實現。3.2以後重新引入了一個quicklist,列表底層都是有quicklist實現,quicklist是一個由ziplist組成的雙向列表,每個節點使用ziplist來存儲數據。
2.1 Lpush命令 lpush key value
將一個或多個值插入到列表頭部。 如果 key 不存在,則創建list,然後再插入數據操作。 當 key 存在但不是列表類型時,返回一個錯誤。
2.2 Rpush命令 rpush key value
將一個或多個值從list的尾部插入
2.3 Blpop命令 blpop key seconds
Blpop是取出列表的第一個元素,如果list中沒有元素則會一直等到到超時,或者發現有數據為止,seconds是指定多少秒返回。如沒有數據,則返回nil。
同理,Bropo為移除list列表的最後一個元素
2.4 Linsert命令 linsert key before/after val1 val2
在list列表的某一個元素前或者後插入另外一個元素。當指的的元素不存在時,不執行任何動作。如果列表不存在時,視為空列表,不執行任何動作。
2.5 Lindex命令 lindex key index
通過鏈表的下標獲取列表中的元素,可以是-1表示鏈表最後一個元素,-2代表倒數第二個元素,沒有返回nil
2.6 Llen命令 llen key
返回list的長度,如果list不存在,返回0
2.7 Lrange命令
返回指定list區間內的元素,區間以偏移量start和end決定。其中 0 表示列表的第一個元素, 1 表示列表的第二個元素,以此類推。 也可以使用負數下標,以 -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。
5.1 隊列秒殺搶購
list類型的lpop和rpush(或者反過來,lpush和rpop)能實現隊列的功能,故而可以用Redis的list類型實現簡單的點對點的消息隊列。不過不推薦在實戰中這么使用,因為現在已經有Kafka、NSQ、RabbitMQ等成熟的消息隊列了,它們的功能已經很完善了,除非是為了更深入地理解消息隊列,不然沒必要去重復造輪子。
5.2 排行榜
list類型的lrange命令可以分頁查看隊列中的數據。可將每隔一段時間計算一次的排行榜存儲在list類型中。只有定時計算的排行榜才適合使用list類型存儲,與定時計算的排行榜相對應的是實時計算的排行榜,list類型不能支持實時計算的排行榜。
⑷ 數據結構 字元串的存儲密度
"如果每個字元佔1個位元組,指針佔2個位元組,該鏈串的存儲密度為3/4" 應是按照指針佔2位元組計算的。在16喂系統是這樣,在32位系統中指針佔4位元組
