一 串
在應用程式中使用最頻繁的型別是字串。字串簡稱串,是一種特殊的線性表,其特殊性在於串中的資料元素是一個個的字元。字串在計算機的許多方面應用很廣。如在彙編和高階語言的編譯程式中,源程式和目標程式都是字串資料。在事務處理程式中,顧客的資訊如姓名、地址等及貨物的名稱、產地和規格等,都被作為字串來處理。另外,字串還具有自身的一些特性。因此,把字串作為一種資料結構來研究。
1 串的基本概念
串(String)由 n(n≥0)字元組成的有限序列。一般記為:
S=”c1c2…cn” (n≥0)
其中, S是串名,雙引號作為串的定界符,用雙引號引起來的字元序列是串值。 ci( 1≤i≤n)可以是字母、數字或其它字元, n為串的長度,當n=0 時,稱為空串(Empty String)。
串中任意個連續的字元組成的子序列稱為該串的子串(Substring)。包含子串的串相應地稱為主串。子串的第一個字元在主串中的位置叫子串的位置。如串s1”abcdefg”,它的長度是 7,串s2”cdef”的長度是 4, s2是s1的子串, s2的位置是 3。
如果兩個串的長度相等並且對應位置的字元都相等,則稱這兩個串相等。而在 C#中,比較兩個串是否相等還要看串的語言文化等資訊。
2 串的儲存和程式碼實現
由於串中的字元都是連續儲存的,而在 C#中串具有恆定不變的特性,即字串一經建立,就不能將其變長、變短或者改變其中任何的字元。所以,這裡不討論串的鏈式儲存,也不用介面來表示串的操作。同樣,把串看作是一個類,類名為 StringDS。取名為 StringDS 是為了和 C#自身的字串類 String 相區別。類StringDS 只有一個欄位,即存放串中字元序列的陣列 data。由於串的運算有很多,類 StringDS 中只包含部分基本的運算。串類 StringDS中的方法和屬性:
//索引器
public char this[int index]
//求串長
public int GetLength()
//串比較
public int Compare(StringDS s)
//求子串
public StringDS SubString(int index, int len)
//串連線
public StringDS Concat(StringDS s)
//串插入
public StringDS Insert(int index, StringDS s)
//串刪除
public StringDS Delete(int index, int len)
//串定位
public int Index(StringDS s)
3 C#中的串
在 C#中,一個 String 表示一個恆定不變的字元序列集合。 String 型別是封閉型別,所以,它不能被其它類繼承,而它直接繼承自 object。因此, String 是引用型別,不是值型別,在託管堆上而不是線上程的堆疊上分配空間。 String 型別還 繼 承 了 IComparable 、 ICloneable 、 IConvertible 、 IComparable 、IEnumerable、 IEnumerable 和 IEquatable等介面。 String 的恆定性指的是一個串一旦被建立,就不能將其變長、變短或者改變其中任何的字元。所以,當我們對一個串進行操作時,不能改變字串,如在本書定義的 StringDS 類中,串連線、串插入和串刪除等操作的結果都是生成了新串而沒有改變原串。 C#也提供了 StringBuilder 型別來支援高效地動態建立字串。
在 C#中,建立串不能用 new 運算子,而是使用一種稱為字串駐留的機制。
這是因為 C#語言將 String 看作是基元型別。基元型別是被編譯器直接支援的型別,可以在原始碼中用文字常量(Literal)來直接表達字串。當 C#編譯器對原始碼進行編譯時,將文字常量字串存放在託管模組的後設資料中。而當 CLR 初始化時, CLR 建立一個空的雜湊表,其中的鍵是字串,值為指向託管堆中字串物件的引用。雜湊表就是雜湊表。當 JIT編譯器編譯方法時,它會在雜湊表中查詢每一個文字常量字串。如果找不到,就會在託管堆中構造一個新的 String 物件(指向字串),然後將該字串和指向該字串物件的引用新增到雜湊表中;如果找到了,不會執行任何操作。
4 C#中的陣列
陣列是一種常用的資料結構,可以看作是線性表的推廣。陣列作為一種資料結構,其特點是結構中的資料元素可以是具有某種結構的資料,甚至可以是陣列,但屬於同一資料型別。陣列在許多高階語言裡面都被作為固定型別來使用。
陣列是 n(n≥1)個相同資料型別的資料元素的有限序列。一維陣列可以看作是一個線性表,二維陣列可以看作是“資料元素是一維陣列”的一維陣列,三維陣列可以看作是“資料元素是二維陣列”的一維陣列,依次類推。
C#支援一維陣列、多維陣列及交錯陣列(陣列的陣列)。所有的陣列型別都隱含繼承自 System.Array。Array 是一個抽象類,本身又繼承自 System.Object。所以,陣列總是在託管堆上分配空間,是引用型別。任何陣列變數包含的是一個指向陣列的引用,而非陣列本身。當陣列中的元素的值型別時,該型別所需的記憶體空間也作為陣列的一部分而分配;當陣列的元素是引用型別時,陣列包含是隻是引用。
5 Array 類中常用方法
using System;
using System.Collections;
public abstract class Array : ICloneable, IList, ICollection, IEnumerable
{
//判斷 Array 是否具有固定大小。
public bool IsFixedSize { get; }
//獲取 Array 元素的個數。
public int Length { get; }
//獲取 Array 的秩(維數)。
public int Rank { get; }
//實現的 IComparable 介面,在.Array 中搜尋特定元素。
public static int BinarySearch(Array array, object value);
//實現的 IComparable<T>泛型介面,在 Array 中搜尋特定元素。
public static int BinarySearch<T>(T[] array, T value);
//實現 IComparable 介面,在 Array 的某個範圍中搜尋值。
public static int BinarySearch(Array array, int index,
int length, object value);
//實現的 IComparable<T>泛型介面,在 Array 中搜尋值。
public static int BinarySearch<T>(T[] array,
int index, int length, T value);
//Array 設定為零、 false 或 null,具體取決於元素型別。
public static void Clear(Array array, int index, int length);
//System.Array 的淺表副本。
public object Clone();
//從第一個元素開始複製 Array 中的一系列元素
//到另一 Array 中(從第一個元素開始)。
public static void Copy(Array sourceArray,
Array destinationArray, int length);
//將一維 Array 的所有元素複製到指定的一維 Array 中。
public void CopyTo(Array array, int index);
//建立使用從零開始的索引、具有指定 Type 和維長的多維 Array。
public static Array CreateInstance(Type elementType,
params int[] lengths);
//返回 ArrayIEnumerator。
public IEnumerator GetEnumerator();
//獲取 Array 指定維中的元素數。
public int GetLength(int dimension);
//獲取一維 Array 中指定位置的值。
public object GetValue(int index);
//返回整個一維 Array 中第一個匹配項的索引。
public static int IndexOf(Array array, object value);
//返回整個.Array 中第一個匹配項的索引。
public static int IndexOf<T>(T[] array, T value);
//返回整個一維 Array 中最後一個匹配項的索引。
public static int LastIndexOf(Array array, object value);
//反轉整個一維 Array 中元素的順序。
public static void Reverse(Array array);
//設定給一維 Array 中指定位置的元素。
public void SetValue(object value, int index);
//對整個一維 Array 中的元素進行排序。
public static void Sort(Array array);
}