JAVA数据结构——串

串:

什么是串?把若干单独个体连接在一起就是一个串。在数据结构中,我们使用的无论是顺序表或者是链表,都是讲个体链接在一起的方法,所以我们利用前面学习的知识,将个体连接在一起实现串的模式匹配(字串在主串中查找的过程),后面将介绍一种简单的子串查找算法BF算法(Brute-Force算法)和KMP算法。

1. 串的概念 字符串简称串,是一种特殊的线性表,它的数据元素仅由一个字符组成。
2. 串的定义 串(String)是由零个或多个字符组成的有限序列,又称字符串。
package com.usts.edu.string;

/**
 * Created by Guanzhong Hu
 * Date :2019/12/28
 * Description : 串的接口
 * Version :1.0
 */
public interface IString {

    public void clear();//将一个已经存在的串置空

    public boolean isEmpty();// 根据串长进行判断,如果为0则为空,上述clear()则是将串置空方法 curlen = 0;

    public int length(); // 根据curlen判断串长

    public char charAt(int index); // 根据指针获取某位置的元素 区间[0,length()-1]

    public IString substring(int begin,int end); // 根据头尾指针切割串,begin & end 区间 [0,length-1].[1,length()]

    public IString insert(int offset,IString str); // 从某个字符插入串,offset区间[0,length()] 因为可以尾巴插入

    public IString delete(int begin,int end); // 从[begin,end] 区间删除串,begin & end 区间 [0,length-1].[1,length()]

    public IString concat(IString str); //把str链接在当前串后

    public int compareTo(IString str); // 当前串和目标串进行比较,当前串 > 目标串 则返回 1,= 返回 0, < 返回-1;

    public int indexOf(IString str,int begin); //从begin搜索非空串str,目标存在则返回index,不存在则返回-1


}
package com.usts.edu.string;

/**
 * Created by Guanzhong Hu
 * Date :2019/12/28
 * Description : 串的顺序存储结构
 * Version :1.0
 */
//TODO
public class SeqString implements IString {

    /**
     * 1、串的概念 字符串简称串,是一种特殊的线性表,它的数据元素仅由一个字符组成。
     * 2、串的定义 串(String)是由零个或多个字符组成的有限序列,又称字符串。
     */
    private char[] strvalue;            //字符数组,存放串值
    private int curlen;                //当前串的长度

    //构造方法1,构造一个空串
    public SeqString() {
        strvalue = new char[0];
        curlen = 0;
    }

    //构造方法2,以字符串常量构造串对象
    public SeqString(String str) {
        if (str != null) {
            char[] tempchararray = str.toCharArray();
            strvalue = tempchararray;
            curlen = tempchararray.length;
        }
    }

    //构造方法3,以字符数组构造串对象
    public SeqString(char[] value) {
        this.strvalue = new char[value.length];
        for (int i = 0; i < value.length; i++) { //复制数组
            this.strvalue[i] = value[i];
        }
        curlen = value.length;
    }

    //将一个已经存在的串置成空串
    public void clear() {
        this.curlen = 0;
    }

    //判断当前串是否为空,为空则返回true,否则返回false
    public boolean isEmpty() {
        return curlen == 0;
    }

    //返回字符串长度
    public int length() {
        return curlen;    //区别: strvalue.length是数组容量
    }

    //返回字符串中序号为index的字符
    public char charAt(int index) {
        if ((index < 0) || (index >= curlen)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return strvalue[index];
    }
    //将字符串中序号为index的字符设置为ch

    public void setCharAt(int index, char ch) {
        if ((index < 0) || (index >= curlen)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        strvalue[index] = ch;
    }

    public void allocate(int newCapacity) //扩充容量,参数指定最小容量
    {
        char[] temp = strvalue;                           //复制数组
        strvalue = new char[newCapacity];
        for (int i = 0; i < temp.length; i++) {
            strvalue[i] = temp[i];
        }
    }

    //返回串中序号从begin至end-1的子串
    public IString substring(int begin, int end) {
        if (begin < 0) {
            throw new StringIndexOutOfBoundsException("起始位置不能小于0");
        }
        if (end > curlen) {
            throw new StringIndexOutOfBoundsException("结束位置不能大于串的当前长度:" + curlen);
        }
        if (begin > end) {
            throw new StringIndexOutOfBoundsException("开始位置不能大于结束位置");
        }
        if (begin == 0 && end == curlen) {
            return this;
        } else {
            char[] buffer = new char[end - begin];
            for (int i = 0; i < buffer.length; i++) //复制子串
            {
                buffer[i] = this.strvalue[i + begin];
            }
            return new SeqString(buffer);
        }
    }

    //返回串中序号从begin至串尾的子串
    public IString substring(int begin) {
        return substring(begin, strvalue.length);
    }

    //在当前串的第offset个字符之前插入串str,0<=offset<=curlen
    public IString insert(int offset, IString str) {
        if ((offset < 0) || (offset > this.curlen)) {
            throw new StringIndexOutOfBoundsException("插入位置不合法");
        }
        int len = str.length();
        int newCount = this.curlen + len;
        if (newCount > strvalue.length) {
            allocate(newCount);             // 插入空间不足,需扩充容量
        }
        for (int i = this.curlen - 1; i >= offset; i--) {
            strvalue[len + i] = strvalue[i];    //从offset开始向后移动len个字符
        }
        for (int i = 0; i < len; i++) //复制字符串str
        {
            strvalue[offset + i] = str.charAt(i);
        }
        this.curlen = newCount;
        return this;
    }
    //删除从begin到end-1的子串, 0≤begin≤length()-1,1≤end≤length()。

    public IString delete(int begin, int end) {
        if (begin < 0) {
            throw new StringIndexOutOfBoundsException("起始位置不能小于0");
        }
        if (end > curlen) {
            throw new StringIndexOutOfBoundsException("结束位置不能大于串的当前长度:" + curlen);
        }
        if (begin > end) {
            throw new StringIndexOutOfBoundsException("开始位置不能大于结束位置");
        }
        for (int i = 0; i < curlen - end; i++) //从end开始至串尾的子串向前移动到从begin开始的位置
        {
            strvalue[begin + i] = strvalue[end + i];
        }
        curlen = curlen - (end - begin);  //当前串长度减去end-begin
        return this;
    }

    //添加指定串str到当前串尾
    public IString concat(IString str) {
        return insert(curlen, str);
    }
    //将字符c连接到到当前串尾

    public IString concat(char c) {
        int newCount = curlen + 1;
        if (newCount > strvalue.length) {
            allocate(newCount);
        }
        strvalue[curlen++] = c;
        return this;
    }

    //比较串
    public int compareTo(IString str) {
        return compareTo((SeqString) str);
    }

    public int compareTo(SeqString str) {  //比较串
        //若当前对象的串值大于str的串值,则函数返回一个正整数
        //若当前对象的串值等于str的串值,则函数返回0
        //若当前对象的串值小于str的串值,则函数返回一个负整数
        int len1 = curlen;
        int len2 = str.curlen;
        int n = Math.min(len1, len2);
        for (int k = 0; k < n; k++) {
            if (strvalue[k] != str.strvalue[k]) {
                return (strvalue[k] - str.strvalue[k]);
            }
        }
        return len1 - len2;   //返回两个字符串长度的数值差
    }

    public String toString() {
        return new String(strvalue, 0, curlen);   //以字符数组strvalue构造串
    }

    //计算模式串T的next[]函数值
    protected int[] getNext(IString T) {
        int[] next = new int[T.length()];  //next[]数组
        int j = 1;    //主串指针
        int k = 0;   //模式串指针
        next[0] = -1;
        if (T.length() > 1) {
            next[1] = 0;
        }
        while (j < T.length() - 1) {
            if (T.charAt(j) == T.charAt(k)) {  //匹配
                next[j + 1] = k + 1;
                j++;
                k++;
            } else if (k == 0) {  //失配
                next[j + 1] = 0;
                j++;
            } else {
                k = next[k];
            }
        }
        return (next);
    }

    //计算模式串T的nextval[]函数值
    protected int[] getNextVal(IString T) {
        int[] nextval = new int[T.length()];  //nextval[]数组
        int j = 0;
        int k = -1;
        nextval[0] = -1;
        while (j < T.length() - 1) {
            if (k == -1 || T.charAt(j) == T.charAt(k)) {
                j++;
                k++;
                if (T.charAt(j) != T.charAt(k)) {
                    nextval[j] = k;
                } else {
                    nextval[j] = nextval[k];
                }
            } else {
                k = nextval[k];
            }
        }
        return (nextval);
    }
}

gitee源码地址:

https://gitee.com/jockhome/data_structure

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是用Java顺序表实现简易通讯录的代码: 首先,在Java中需要定义一个类来表示通讯录中的每一个联系人,这个类包含联系人的姓名和电话号码两个属性: ```java public class Contact { private String name; private String phoneNumber; public Contact(String name, String phoneNumber) { this.name = name; this.phoneNumber = phoneNumber; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } } ``` 接下来,我们用一个顺序表来存储所有的联系人信息: ```java public class ContactList { private Contact[] contacts; private int size; public ContactList(int capacity) { contacts = new Contact[capacity]; size = 0; } public boolean add(Contact contact) { if (size >= contacts.length) { return false; } contacts[size++] = contact; return true; } public boolean remove(int index) { if (index < 0 || index >= size) { return false; } for (int i = index; i < size - 1; i++) { contacts[i] = contacts[i + 1]; } contacts[--size] = null; return true; } public Contact get(int index) { if (index < 0 || index >= size) { return null; } return contacts[index]; } public int size() { return size; } } ``` 在这个类中,我们定义了一个Contact类型的数组来存储所有的联系人信息,同时还有一个size变量来记录当前已经存储的联系人数目。在这个类中,我们提供了以下几个方法: - add(Contact contact):向通讯录中添加一个联系人,如果当前已经存储的联系人数目已经达到了数组的容量,则添加失败。 - remove(int index):根据给定的下标从通讯录中删除一个联系人,如果给定的下标越界,则删除失败。 - get(int index):根据给定的下标获取通讯录中指定位置的联系人,如果给定的下标越界,则返回null。 - size():获取当前通讯录中已经存储的联系人数目。 我们可以使用这个类来实现一个简单的通讯录应用程序,这个程序可以让用户输入联系人的姓名和电话号码,然后将其添加到通讯录中,也可以让用户删除指定位置的联系人,还可以列出所有已经存储的联系人信息。下面是这个应用程序的代码: ```java import java.util.Scanner; public class ContactApp { public static void main(String[] args) { ContactList contactList = new ContactList(10); Scanner scanner = new Scanner(System.in); while (true) { System.out.println("请选择操作:"); System.out.println("1. 添加联系人"); System.out.println("2. 删除联系人"); System.out.println("3. 列出所有联系人"); System.out.println("4. 退出"); int choice = scanner.nextInt(); scanner.nextLine(); switch (choice) { case 1: System.out.println("请输入联系人姓名:"); String name = scanner.nextLine(); System.out.println("请输入联系人电话号码:"); String phoneNumber = scanner.nextLine(); Contact contact = new Contact(name, phoneNumber); if (contactList.add(contact)) { System.out.println("添加成功!"); } else { System.out.println("添加失败,通讯录已满!"); } break; case 2: System.out.println("请输入要删除联系人的下标:"); int index = scanner.nextInt(); if (contactList.remove(index)) { System.out.println("删除成功!"); } else { System.out.println("删除失败,下标越界!"); } break; case 3: System.out.println("所有联系人信息:"); for (int i = 0; i < contactList.size(); i++) { Contact c = contactList.get(i); System.out.println((i + 1) + ". " + c.getName() + " " + c.getPhoneNumber()); } break; case 4: System.out.println("谢谢使用!"); return; default: System.out.println("输入错误,请重新输入!"); break; } } } } ``` 这个应用程序首先创建了一个ContactList对象来存储所有的联系人信息。然后,它通过一个无限循环来等待用户输入选择,并根据用户的选择执行相应的操作。当用户选择退出程序时,程序会结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值