串的基本概念
串(也稱作字符串)是由n(n≥0)個字符組成的有限序列。
一個串中任意個連續的字符組成的子序列稱爲該串的子串。 包含子串的串稱爲該子串的主串。
一個字符在一個串中的位置序號(爲大於等於0的正整數)稱爲該字符在串中的位置。當且僅當這兩個串的值完全相等時,稱這兩個串相等。
串抽象數據類型
數據集合:串的數據集合可以表示爲字符序列s0, s1,… , sn-1,每個數據元素的數據類型爲字符類型。
操作集合:
(1)取字符charAt(index) :取index下標的字符返回。
(2)求長度length():返回串的長度。
(3)比較compareTo(anotherString):比較當前對象串和串anotherString的Unicode碼值的大小。
(4)取子串substring(beginIndex,endIndex):取當前對象串中從beginIndex下標開始、至endIndex下標的前一下標止的子串。
(5)連接concat(str):把串str連接到當前對象串的末尾。
(6)插入子串insert(str, pos):在當前對象串的第pos個字符前插入子串str。
(7)刪除子串delete(beginIndex,endIndex):刪除當前對象串中從beginIndex下標開始、至endIndex下標的前一下標止的子串 。
(8)輸出串值myPrint():輸出當前對象的串值。
//建議重寫Object類的toString()方法。使用toString()代替
(9)查找子串index(subStr,start):在當前對象串的start下標開始,查找是否存在子串subStr。串的存儲結構
}串的順序存儲結構
串的順序存儲結構就是用字符類型數組存放串的所有字符。表示串的長度通常有兩種方法:
(1)設置一個串的長度參數。
(2)在串值的末尾添加結束標記。
串值長度的第一種表示方法下,串的成員變量應包括如下兩項:
char[] value;
int count;
其中,value爲存儲串值的字符類型數組名,count表示串值的長度。
設計MyString類
//用戶自定義的MyString類
public class MyString {
private char[] value; //字符數組
private int count; //字符串的長度
//從源串指定下標開始拷貝指定長度的字符串到目標串指定爲下標開始
//char[] src:源串
//int srcPos:源串的開始下標
//char[] dst:目標串
//int dstPos:目標串開始下標
//int length:拷貝長度
public static void arrayCopy(char[] src,int srcPos,char[] dst,int dstPos,int length)
{
//如果源串起始下標+拷貝長度>源串長度或者目標串起始下標+拷貝長度>目標串長度
if(srcPos+length>src.length||dstPos+length>dst.length)
{
throw new StringIndexOutOfBoundsException(length);
}
for(int i=0;i<length;i++)
{
dst[dstPos++]=src[srcPos++];
}
}
//構造方法1,構造一個空字符串
public MyString()
{
value=new char[0];
count=0;
}
//構造方法2,實現從一個字符數組中提取出新的字符串。
//char[] value:已有的字符數組。
//int offset:起始下標
//int count:拷貝的個數
public MyString(char[] value,int offset,int count)
{
//判斷起始位置是否<0
if(offset<0)
{
throw new StringIndexOutOfBoundsException(offset);
}
//判斷count是否<0
if(count<0)
{
throw new StringIndexOutOfBoundsException(count);
}
//判斷起始位置+count是否大於value字符串的長度
if(offset+count>value.length)
{
throw new StringIndexOutOfBoundsException(offset+count);
}
this.value = new char[count];
this.count = count;
arrayCopy(value,offset,this.value,0,count);
}
//構造方法3,根據已有的字符數組,構造新的字符串
public MyString(char[] value)
{
this.count = value.length;
this.value = new char[count];
arrayCopy(value,0,this.value,0,count);
}
//構造方法4,使用JDK本身的String類,構造新的字符串
public MyString(String str)
{
char[] chararray = str.toCharArray();
value = chararray;
count = chararray.length;
}
@Override
public String toString() {
// TODO Auto-generated method stub
String str="";
for(int i=0;i<count;i++)
{
str+=value[i];
}
return str;
}
public int length()
{
return count;
}
public char charAt(int index)
{
if(index<0||index>=count)
{
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
//比較兩個字符串的大小
//如果當前字符串大於比較字符串,返回一個正整數
//如果當前字符串等於比較字符串,返回0
//如果當前字符串小於比較字符串,返回負整數
public int compareTo(MyString anotherStr)
{
int len1= this.count;
int len2 = anotherStr.length();
int n = Math.min(len1, len2);
char[] v1 = value;
char[] v2 = anotherStr.value;
int i=0;
while(i<n)
{
char c1 =v1[i];
char c2 =v2[i];
if(c1!=c2)
{
return c1-c2;
}
i++;
}
return len1-len2;
}
//求子串1,給出起始下標
public MyString substring(int beginIndex,int endIndex)
{
if(beginIndex<0)
{
throw new StringIndexOutOfBoundsException(beginIndex);
}
if(endIndex>count)
{
throw new StringIndexOutOfBoundsException(endIndex);
}
if(beginIndex>endIndex)
{
throw new StringIndexOutOfBoundsException(endIndex-beginIndex);
}
return (beginIndex==0&&endIndex==count)?this:new MyString(value,beginIndex,endIndex-beginIndex);
}
//求子串2,給出開始下標,到字符串末尾
public MyString substring(int beginIndex)
{
return substring(beginIndex,count);
}
public char[] toCharArray()
{
char[] buff = new char[count];
arrayCopy(value,0,buff,0,count);
return buff;
}
//字符串的連接
public MyString concat(MyString str)
{
int otherLen = str.length();
char[] strarray = str.toCharArray();
if(otherLen==0)
{
return this;
}
char[] buff = new char[count+otherLen];
arrayCopy(value,0,buff,0,count);
arrayCopy(strarray,0,buff,count,otherLen);
return new MyString(buff);
}
//插入子串
public MyString insert(MyString str,int pos)
{
if(pos<0||pos>count)
{
throw new StringIndexOutOfBoundsException(pos);
}
if(pos!=0)
{
//獲得插入點之前的子串
MyString str1 =this.substring(0, pos);
//獲得插入點之後的子串
MyString str2 = this.substring(pos);
MyString res1 = str1.concat(str);
MyString res2 = res1.concat(str2);
return res2;
}
else
{
return str.concat(this);
}
}
//刪除子串
public MyString delete(int beginIndex,int endIndex)
{
if(beginIndex<0)
{
throw new StringIndexOutOfBoundsException(beginIndex);
}
if(endIndex>count)
{
throw new StringIndexOutOfBoundsException(endIndex);
}
if(beginIndex>endIndex)
{
throw new StringIndexOutOfBoundsException(endIndex-beginIndex);
}
//刪除整個字符串
if(beginIndex==0&&endIndex==count)
{
return new MyString();
}
else
{
//獲得刪除點前的子串
MyString str1 = this.substring(0,beginIndex);
//獲得刪除子串後的子串
MyString str2 = this.substring(endIndex);
return str1.concat(str2);
}
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
char[] c1={'c','h','i','n','a'};
char[] c2={'I','l','o','v','e',' ','c','h','i','n','a'};
//構造方法1
MyString str1= new MyString();
//構造方法3
MyString str2 = new MyString(c1);
//構造方法2
MyString str3 = new MyString(c2,1,5);
//構造方法4
MyString str4 = new MyString("Hello ");
MyString str5 = new MyString("China");
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
System.out.println(str4.length());
System.out.println(str3.charAt(2));
System.out.println(str5);
System.out.println(str5.hashCode());
str5 =str5.concat(str4);
System.out.println(str5);
System.out.println(str5.hashCode());
}
}