day19 字符串匹配
1. 思路
字符串匹配,将子串和主串进行匹配。若子串和主串不匹配,则主串从下一个字符开始与子串重新开始匹配,直到多次匹配结束都无匹配则返回不匹配有则返回地址。这样两个串的“指针”都要回溯。若用KMP,则只需要回溯子串指针。
2. 代码
package main.java.datastructure;
import sun.applet.Main;
import java.time.Year;
public class MyString {
/**
* The maximal length.
*/
public static final int MAX_LENGTH = 10;
/**
* The actual length.
*/
int length;
/**
* The data.
*/
char[] data;
/**
* Construct an empty char array.
*/
public MyString(){
length = 0;
data = new char[MAX_LENGTH];
}
/**
*Construct using a system defined string.
* @param paraString The given string. Its length should not exceed MAX_LENGTH - 1.
*/
public MyString(String paraString){
data = new char[MAX_LENGTH];
length = paraString.length();
for (int i = 0; i < length; i++){
data[i] = paraString.charAt(i);
}
}
public String toString(){
String resultString = "";
for (int i = 0; i < length; i++){
resultString += data[i];
}
return resultString;
}
/**
* Locate the position of a substring.
* @param paraString The given substring.
* @return The first position. -1 for no matching.
*/
public int locate(MyString paraString){
boolean tempMatch = false;
for (int i = 0; i < length - paraString.length + 1; i++){
tempMatch = true;
for (int j = 0; j < paraString.length; j++){
if (data[i+j] != paraString.data[j]){
tempMatch = false;
break;
}
}
if (tempMatch){
return i;
}
}
return -1;
}
/**
* Get a substring
* @param paraStartPosition The start position in the original string.
* @param paraLength The length of the new string.
* @return The first position. -1 for no matching.
*/
public MyString substring(int paraStartPosition, int paraLength){
if (paraStartPosition + paraLength > length){
System.out.println("The bound is exceeded.");
return null;
}
MyString resultMyString = new MyString();
resultMyString.length = paraLength;
for (int i = 0; i < paraLength; i++){
resultMyString.data[i] = data[paraStartPosition + i];
}
return resultMyString;
}
public static void main(String args[]) {
MyString tempFirstString = new MyString("I like ik.");
MyString tempSecondString = new MyString("ik");
int tempPosition = tempFirstString.locate(tempSecondString);
System.out.println("The position of \"" + tempSecondString + "\" in \"" + tempFirstString
+ "\" is: " + tempPosition);
MyString tempThirdString = new MyString("ki");
tempPosition = tempFirstString.locate(tempThirdString);
System.out.println("The position of \"" + tempThirdString + "\" in \"" + tempFirstString
+ "\" is: " + tempPosition);
tempThirdString = tempFirstString.substring(1, 2);
System.out.println("The substring is: \"" + tempThirdString + "\"");
tempThirdString = tempFirstString.substring(5, 5);
System.out.println("The substring is: \"" + tempThirdString + "\"");
tempThirdString = tempFirstString.substring(5, 6);
System.out.println("The substring is: \"" + tempThirdString + "\"");
}
}
day20 小结
1.面向对象与面向过程相比, 有哪些优势?
面向过程我们主要放在操作步骤上,如之前写的“矩阵相加”,而这个类主要就是完成一个功能及如何完成矩阵相加,MatrixAddition
面向对象:例如之前写了一个链表类,我们把链表类抽象为一个类对象,在这个对象有自己的变量和方法,实现了查找,插入,删除等功能,当我想用其中任何一个方法,我可以通过对象去调用,当我想用另一个方法时,发现没有,我可以去对象中加,以后也可以复用方法。
所以面向对象更容易扩展修改,更容易模块化,减少代码的冗余。
2.比较顺序表和链表的异同;分析顺序表和链表的优缺点
(1)顺序表在定义时需要预先分配空间,顺序表在插入和删除时,需要遍历顺序表且需要移动元素;链表在定义时不需要预先分配空间,可以动态分配而链表在插入时只需要改变他的指针指向 (2)查找数据,对于顺序表(通过数组来标识),只要给出查找位置,直接可以定位到数据,查找方便 但增删很慢。对于链表,必须要从头节点开始查找,查找慢;但增删快。
3.分析调拭程序常见的问题及解决方案
(1) 空指针异常 在写代码过程中,对可能出现为空的要对代码多加一层为空的判断保护代码。例如数组已为null,还要去取数据;对象为null还要去取对象某个值。 (2)数组越界异常 在初始化数组,对长度的定义要合适并且要在有数组进行增删是要多一层判断数组成都操作
4. 分析链队列与循环队列的优缺点.
相比于链队列,循环队列对空间利用率更大,删除后的元素空间还可以再利用,但循环队列大小是提前定义好了,不像链队列能动态增加。
5. 是否合理
第 18 天建立的两个队列, 其区别仅在于基础数据不同, 一个是 int, 一个是 char. 按这种思路, 对于不同的基础数据类型, 都需要重写一个类, 这样合理吗? 你想怎么样 这样不合理,不满足面向对象思想。可以使用泛型。但我使用Object类型来实现,因为Object类是所以类的超类,并试用int和char类型都可以满足,但正因为Object类任何类型都能接收,可能会在运行中出现bug。
public static final int TOTAL_SPACE = 10;
Object[] data;
//The index for calculating the head
int head;
//The index for calculating the tail
int tail;
public CircleQueue () {
data = new Object[TOTAL_SPACE];
head = 0;
tail = 0;
}