数据结构 C#描述 第七章 (第一部分)
第七章:字符串,String类,,StringBuilder类
字符串在计算机程序中是最常用的。在某类程序中,例如字处理和web程序中,用大了大量的字符串,使得程序员花大量的精力在考虑字符串的效率的上。本章中,我们将看看C#是怎样处理字符串的,怎样应用String类,最后又是怎样应用StringBuilder类的。StringBuilder类被用在当一个程序要多次改变一个字符串时,因为String类是不变的,而StringBuiler类是变化的。
String类的工作
字符串是包含了字符,数字,以及其他的符号的集合。字符串在C#语言中是用双引号来包括的。如下:
"David Ruff"
"the quick brown fox jumped over the lazy dog"
"123-45-6789"
"mmcmillan@pulaskitech.edu"
一个字符串可以由任何Unicode字符组成。一个字符串中也可以不包含字符。这种特殊的字符串称之为空串,用两个相邻的双引号表示。记住,空格串不是空串。
创建String类
字符串创建如下:
string name = "Jennifer Ingram";
当然,也可以先申明一个变量,然后给变量赋值。这种申明方式看起来仅仅只是申明一个一般的变量,但是实际上是一个字符串的实例。
C#字符串海允许你在字符串中用转义符。C和C++中也用了相似的技术,这对有VB北京的人来可以说是全新的技术。转义符被用来做格式字符,例如,换行,用tap键后退。转义符以一条反斜杠开始“\”,后面紧跟一个字符。例如,\n就是换行。如下,转义符被用在一个字符串中:
string name = "Mike McMillan\nInstructor, CIS\tRoom 306";
String类常用的方法
虽然在字符串上有很多的操作,但是只有少部分操作是主要的。主要的三种操作如下:1.在一个串中查找子串;2.确定串的长度。3.确定一个字符在串中的位置。
下面的程序段就说明了怎样利用这些操作。一个字符串被初始化为”Hello world”,我可以将这个串分为两个串:前一个单词为一个串,后面的又是一个。代码如下:
using System;
public class Chapter7
{
static void
{
string string1 = "Hello world!";
int len = string1.Length;
int pos = string1.IndexOf(" ");
string firstWord, secondWord;
firstWord = string1.Substring(0, pos);
secondWord = string1.Substring(pos + 1, (len - 1) - (pos + 1));
Console.WriteLine("First word:" + firstWord);
Console.WriteLine("Second word:" + secondWord);
Console.Read();
}
}
我们做的第一件事就是用Length属性求出string1的长度。长度就是一个字符串中所有字符的个数。我们在后面将会介绍为什么要知道字符串的长度。
在两个单词的串分为两个单独的字符串,我们要知道分割符是什么。在一个格式很好的字符串中,空格就是分隔符,因此我们就想找出两个单词之间的空格的位置。可以用IndexOf方法。这个方法用有一个参数,并且返回分隔符在串中的位置。C#中的字符串中的字符的位置是从0开始的。如果在串中没有找到某个字符,就返回-1.
IndexOf方法找出分隔符的位置,然后用SubString方法来将第一个单词从串中提出。Substring方法要两个参数:在串中的起始位置,要获取多少个字符。如下:
string s = "Now is the time";
string sub = s.Substring(0,3);
sub的结果是”Now”,你要你愿意,你可以从串中取得更多的字符出来,但是如果你获取的个数超过了串的长度就会产生异常。
下一步就是获取第二个参数。因为我们已经知道了空格的位置,我们就知道了第二个单词的起始位置是pos+1。最难的部分就是确定要获取多少个字符,如果操作有误就会产生异常。有些固定的方法可以让我们来用。首先,我们在找到空格的位置加1,然后用串的长度来减去空格的位置加1后的数。我们就可以准确的得到我们要获取的字符个数。
尽管我们之前的程序很有意思,但是不是很实用。我们需要的是从任何一个长度的格式好的串中获取单词。有些算法可以实用:
算法的步骤如下:
1. 找出第一个空格在串中的位置
2. 获取单词
3. 创建一个新的串,这个串由空格起始位置到串结尾的字符组成
4. 在新串中查找另外的空格
5. 如果没有其他的空格,就截取整个新串
6. 否则,回到步骤2
代码如下:
using System;
using System.Collections;
public class Chapter7
{
static void
{
string astring = "Now is the time";
int pos;
string word;
ArrayList words = new ArrayList();
pos = astring.IndexOf(" ");
while(pos>0)
{
word = astring.Substring(0, pos);
words.Add(word);
astring = astring.Substring(pos + 1, astring.Length - (pos + 1));
pos = astring.IndexOf(" ");
if (pos == -1)
{
word = astring.Substring(0, astring.Length);
words.Add(word);
}
}
Console.Read();
}
}
当然,如果我们想用这个算法,可以将它写成一个返回数组的方法,如下:
using System;
using System.Collections;
public class Chapter7
{
static void
{
string astring = "now is the time for all good people";
ArrayList words = new ArrayList();
words = SplitWords(astring);
foreach(string word in words)
{
Console.Write(word + " ");
}
Console.Read();
}
static ArrayList SplitWords(string astring)
{
ArrayList words = new ArrayList();
int pos;
string word;
pos = astring.IndexOf(" ");
while (pos > 0)
{
word = astring.Substring(0, pos);
words.Add(word);
astring = astring.Substring(pos + 1, astring.Length - (pos + 1));
pos = astring.IndexOf(" ");
if (pos == -1)
{
word = astring.Substring(0, astring.Length);
words.Add(word);
}
}
return words;
}
}
String 类有一个方法可以将字符串分割,同时也有一个方法将数组的数据合并为一个字符串。下面来看看这些方法。
Splite和Join方法
将一个字符串分割为很多的片段是很常用的操作。在很多的程序中,从web程序到每天的office程序,都是将数据以字符的某种格式来保存的。String类提供了两个方法:Split方法来将字符串分割,Join方法将集合中的数据连接成为一个字符串
Splite 方法获取一个字符串,将它分割为连续的片段,并且将这些片段放入字符串数组中。这个方法用一个分隔的的参数,来确定从字符串的哪里分割。当我们用Split方法时,可以选定分隔符。实际上,分隔符是这个方法的第一个参数。
很多的程序应用中用逗号来做分隔符。
“Mike, McMillan,3000 W. Scenic,
字符串data中的每一段都由逗号分开。我们可以用数组来存储用Split方法分割的每一段。如下:
string data="Mike,McMillen,3000,W.Senic,
string[] sdata;
char[] delimiter=new char[]{','};
sdata=data.Split(delimiter,data.Length);
现在我们可以用标准的方法来访问这个数组:
foreach(string word in sdata)
Console.WriteLine(word+" ");
我们还可以给Split方法传入另外一个参数:我们想要存储在数组中的元素的个数。例如,如果我想把字符串中的第一段作为数组中的第一个元素,而把其他的作为数组中的第二个元素,我们可以这样做:
sdata = data.Split(delimiter,2);
数组中的元素如下:
第一个元素(索引从零开始):Mike
第二个元素:McMillen,3000,W.Senic,
我们还可以用其他的方法把数组中的元素连成字符串,如 Join方法。这个方法要传入两个参数:连接的数组,分割符。字符串是有分隔符后的每一段组成的。我们要知道,这个方法是一个类的方法。意味着这个方法是String类的方法,而不是String类的实例的方法。
例如:
using System;
public class Chapter7
{
static void
{
string data = "Mike,McMillan,3000 W.Secenic.North Little Rock,AR,72108";
string[] sdata;
char[] delimiter = new char[] { ',' };
sdata = data.Split(delimiter, data.Length);
foreach (string word in sdata)
Console.WriteLine(word + " ");
string joined;
joined = String.Join(",", sdata);
Console.Write(joined);
}
}
比较就知道data和joined是一样的。这些方法在你的程序中很有用。
字符串的比较方法
在C#中有很多的方法可以来比较String类。最常用的方法就是用比较运算符,而且在很多情况下这种方法都运行的很好。但是,还有一些情况下,另外的比较方法更好,例如,如果我们想知道一个字符串是比另外一个大,还是小,还是相等,在这种情况下,我们就得在String类中找方法来实现。
比较字符串就像比较数字一样。但是,由于“a”是否大于还是小于“H”,他们的大小不是那么的明显,所以我们必须将其换算为数字。换算方法就是用Unicode。每一个字符都有一个Unicode值。你可以用ASC函数还确定一个字符的Unicode值。ASC对应的是字符的ASCII编码。
要找到字符的ASCII值,用一个简单的转换就可以了:
int charCode;
charCode = (int)'a';
变量中存储的就是97.
两个字符串的比较,实际上就是在比较二者的编码。字符串“a”和“b“不相等是因为97不等于98.。我们简单的来看看他的用法。
我们首先来看看Equal方法。这个方法被一个字符串对象调用,同时还传入另外的一个字符串对象为参数。如果两个比较的字符串对象包含的字符相同就返回true,否则就是false。如下:
string s1="foobar";
string s2="foobar";
if(s1.Equals(s2))
Console.WriteLine("They are the same";
else
Console.WriteLine("They are not the same";
下一个比较字符串的方法就是CompareTo方法。这个方法也要传入一个字符串作为参数,但是方法不返回布尔值。相反方法返回1,或-1,或9,返回哪一个要取决于比较的两个串之间的大小。如下:
string s1="foobar";
string s2="foobar";
Console.WriteLine(s1.CompareTo(s2)); //返回
s2="foofoo";
Console.WriteLine(s1.CompareTo(s2)); //返回-1
s2="fooarr";
Console.WriteLine(s1.CompareTo(s2)); //返回
还可以用Compare方法来代替CompreTo的用法,但是要记住Compare方法是类的方法,即静态方法。这个方法要传入两个要比较的对象,返回值和CompareTo的一样。如下:
using System;
public class Chapter7
{
static void
{
string s1 = "foobar";
string s2 = "foobar";
int compVal = String.Compare(s1, s2);
switch (compVal)
{
case 0:
Console.WriteLine(s1 + " " + s2 + " are equal");
break;
case 1:
Console.WriteLine(s1 + " " + " are more than" +s2 );
break;
case -1:
Console.WriteLine(s1 + " " + " are less than" + s2);
break;
}
}
}
还有其他的一些很有用字符串的比较方法:StartsWith,EndsWith。这些实例方法传入一个字符串为参数,如果实例的开头和结尾和传入的的参数相同就返回true。
代码实例如下:下看看EndsWith方法
using System;
using System.Collections;
public class Chapter7
{
static void
{
string[] nouns = new string[]{
"cat","dog","bird","eggs"};
ArrayList pN = new ArrayList();
foreach (string n in nouns)
{
if (n.EndsWith("s"))
pN.Add(n);
}
foreach (string n in pN)
Console.Write(n + " ");
}
}
首先,我们创建了一个nouns数组,数组中的有些名称是复数的,然后我们循环遍历数组中的元素,检查名词是否是复数(以s结尾的)。如果是,就添加到数组中。然后显示出来。
同理,我们来看看那些单词是以“tri“开头的:
using System;
using System.Collections;
public class Chapter7
{
static void
{
string[] nouns = new string[]{
"triangle",
"diagonal",
"trimester",
"bifocal"
};
ArrayList pN = new ArrayList();
foreach (string n in nouns)
{
if (n.StartsWith ("tri"))
pN.Add(n);
}
foreach (string n in pN)
Console.Write(n + " ");
}
}
更多操作字符串的方法
在字符串处理的时候经常使得字符串改变。例如,我们要在现有的字符串中插入新的字符,或者在串中移除一字符,以及替换字符,只要调用这些操作相对有的名字就可以了。
我们首先看Insert插入方法。这个方法在现有的字符串中的某一指定的位置插另外的字符串。Insert方法返回新的字符串:如下:
using System;
using System.Collections;
public class Chapter7
{
static void
{
string s1 = "Hello,.Welcome to my class.";
string name = "xiaoyang";
int pos = s1.IndexOf(",");
s1 = s1.Insert(pos + 2, name);
Console.WriteLine(s1);
}
}
输出如下:
Hello,.xiaoyangWelcome to my class.
这段程序先创建一个字符串s1,而且串中留了空间给名字,就像你在写信时暂时没有写上收信人的名字一样。我们在找到了逗号之后的位置再加2,就找到了我们要写名字的地方。
下一个方法介绍Remove。方法要传入两个参数:起始位置,和个数。代码如下:将程序中的名字删除:
using System;
using System.Collections;
public class Chapter7
{
static void
{
string s1 = "Hello,.Welcome to my class.";
string name = "xiaoyang";
int pos = s1.IndexOf(",");
s1 = s1.Insert(pos + 2, name);
Console.WriteLine(s1);
s1 = s1.Remove(pos + 2, name.Length);
Console.WriteLine(s1);
}
}
结果显示如下:
Hello,.xiaoyangWelcome to my class.
Hello,.Welcome to my class.
我们下面将会介绍Replace方法。方法要传入两个参数:字符串中要删除的字符,准备替换的字符。代码如下:
using System;
using System.Collections;
public class Chapter7
{
static void
{
string[] words = new string[]{
"recieve","decieve","recipet"};
for (int i = 0; i < words.GetUpperBound(0); i++)
{
words[i] = words[i].Replace("cie", "aaa");
Console.WriteLine(words[i]);
}
}
}
当我们的程序在显示数据的时,我们想让数据以某种格式排列。String类有两个方法来做:PadLeft 和PadRight。如下:
string s1="Hello";
Console.WriteLine("s1.PadLeft(10));
Console.WriteLine("world");
显示如下:
Hello
.world
下面是PadRight例子
string s1 = "Hello";
string s2 = "world";
string s3 = "Goodbye";
Console.Write(s1.PadLeft(10));
Console.WriteLine(s2.PadLeft(10));
Console.Write(s3.PadLeft(10));
Console.WriteLine(s2.Padleft(10));
显示如下
Hello world
Goodbye world