串(也称作字符串)是由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表示串值的长度。串的链式存储结构
串的链式存储结构就是把串值分别存放在构成链表的若干个结点的数据元素域上。 有单字符结点链和块链两种。
单字符结点链就是每个结点的数据元素域只包括一个字符。
块链就是每个结点的数据元素域包括若干个字符。- 代码实现
public class MyString {
private char[] value;//字符数组
private int count;//字符串长度
/**
* 从源串指定下标开始拷贝指定长度的字符串到目标串指定为下标开始
* @param src 源串
* @param srcPos 源串的开始的下标
* @param dst 目标串
* @param dstPos 目标串开始下标
* @param 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++];
}
}
//构造方法一,构造一个空字符串
public MyString(){
value = new char[0];
count = 0;
}
/**
* 实现从一个字符中提取出新的字符串。
* @param value 已有的字符数组
* @param offset 起始下标
* @param 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);
}
/**
* 根据已经有的字符串数组,构造新的字符串
* @param value
*/
public MyString(char[]value){
this.count = value.length;
this.value = new char[count];
arrayCopy(value,0,this.value,0,count);
}
/**
* 使用JDK本身的String类,构造新的字符串
* @param str
*/
public MyString(String str)
{
char[] chararray = str.toCharArray();
value = chararray;
count = chararray.length;
}
public String toString(){
String str = "";
for (int i = 0;i<count;i++) {
str += value[0];
}
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
//如果当前字符串小于比较字符串,返回负整数
* @param anotherStr
* @return
*/
public int compareTo(MyString anotherStr){
int length1 = this.count;
int length2 = anotherStr.length();
int n = Math.min(length1, length2);
char[] value1 = value;
char[] value2 = anotherStr.value;
int i = 0;
while (i < n) {
char c1 = value1[i];
char c2 = value2[i];
if (c1 != c2) {
return c1 - c2;
}
i++;
}
return length1=length2;
}
}
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(str2.compareTo(str5));
}
}