{
private final //最终变量,存储浮点数
double value;
//以下方法体省略 public value) MyDouble(double //由double值构造浮点数对象
public MyDouble(String s) throws NumberFormatException //由字符串s构造浮点数对象 public double doubleValue() //返回浮点数值 public String toString() //返回浮点数值的字符串 public int dobj) compareTo(MyDouble //比较两个对象值大小
//返回实数字符串s表示的浮点数,语法图见教材图3.21(a),由数字序列和运算符构造实数
public static double parseDouble(String s) throws NumberFormatException
//返回实数串s表示的浮点数,语法见教材图3.21(b),由整数、数字序列和运算符构造实数
public static double toDouble(String s) {
int dot=s.indexOf('.'),e=s.indexOf('E'); //寻找小数点和E
if (e==-1)
e=s.indexOf('e'); if (dot==-1 && e==-1) return MyInteger.parseInt(s); //s中没有小数和阶码,返回整数
int i=0,sign=s.charAt(0)=='-' ? -1 : 1; //sign记住符号位
if (s.charAt(0)=='+' || s.charAt(0)=='-') //跳
- 28 -
过符号位
i++;
double value=0,power=0.1; //power表示底为10的幂,赋值为整数
if (dot!=-1) //s中有小数部分
{ value=MyInteger.parseInt(s.substring(i,dot)); //获得正整数部分值
dot++; //跳过小数点
while (dot
{ value += (s.charAt(dot)-'0')*power; dot++;
power*=0.1; } }
value *=sign;
if (e!=-1) //处理阶码
{ if (dot==-1) //s中没有小数部分
value=MyInteger.parseInt(s.substring(0,e)); //获得整数部分值
e++;
power = (s.charAt(e)=='-') ? 0.1 :10; //阶码的符号位决定指数的正负及运算
if (s.charAt(e)=='+' || s.charAt(e)=='-') e++;
int exp=MyInteger.parseInt(s.substring(e)); //获得指数部分的正整数值
for (int j=0; j - 29 - return value; } } 3.2.3 变量字符串类 【实验题3-11】删除变量串中的所有空格。 阅读程序,回答以下问题。 public static StringBuffer trim(StringBuffer s) //将s中所有空格删除,返回操作后的s串 { int i=0,j=0; while (i i++; for (j=i; j s.setCharAt(i++,s.charAt(j)); //非空格字符向前移动到空格字符位置 return s; } ① 对于以下调用语句,运行结果是什么?正确的运行结果是什么? StringBuffer str = new StringBuffer(\ a bc d e f xyz\System.out.println(\ ② trim()方法怎样实现所求功能?算法存在什么错误? ③ 如何改正? 【答】① 运行结果为“abcdefxyz e f xyz”,正确的运行结果是“abcdefxyz”。 ② trim()方法首先寻找串的第一个空格字符,用i记住空格字符下标;再遍历串,将串中的非空格字符(用j记住其下标)逐个向前移动到空格字符位置(i下标);算法如图3.3(a)所示。算法存在错误,删除后没有将改变字符串长度变量n减少,导致仍然输出原长度n个字符,如图3.3(b)所示。 - 30 - 0valuei1ajbcd??efxyn-1z?length-10a1??n-1nzi?efxyz剩余空间?bcdefxy(a)字符串初始状态,i表示空格字符下标,j表示非空格字符下标?length-1value使用空间(b)删除后的串j 图3.3 删除StringBuffer字符串对象中的所有空格 ③ 改正:方法体return语句前增加以下一句: str.setLength(i); //设置串长度为i 3.3 串的模式匹配 3.3.1 Brute-Force模式匹配算法 3-8 什么是串的模式匹配?有哪些场合需要使用串的模式匹配? 【答】串的模式匹配指,在目标串中查找与模式串相等的一个子串并确定该子串位置的操作。若要删除或替换已知字符串中的指定子串,则首先要执行模式匹配操作,在已知串中查找是否有匹配的子串,获得子串位置,再进行查找或替换等操作。 3-9 Brute-Force模式匹配算法的主要特点是什么?算法思路是怎样的?给出最好情况和最坏情况及其时间复杂度。 【答】Brute-Force是一种带回溯的模式匹配算法,它将目标串中所有长度为m的子串依次与模式串匹配,如果一次匹配失败,则模式串再与目标串的下一个子串匹配。 Brute-Force算法最好情况下的时间复杂度是O(m),最坏情况下的时间复杂度是O(m×n)。 习3-9② 已知target=\、pattern=\,画出采用Brute-Force算法的模式匹配过程,给出比较结果、子串匹配次数和字符比较次数。 【答】比较结果:匹配不成功,匹配子串位置为-1;子串匹配6次,字符比较17次。 - 31 - t0targetat1at2at3bt4at5at6at7bt8at0targetat1at2at3bt4aat5at6at7bt8at0targetat1at2at3bt4aat5aat6at7bt8a===≠==≠=patternapatternaaaapatternaaa≠a(a)比较4次targetaaabaaaaaabatargetaa(b)比较3次abaaabatargetaa(c)比较2次abaaabaa =a≠===≠=patternapatternaaaapatterna(d)比较1次(e)比较4次,匹配失败(f)比较3次,匹配失败图3.4 模式串\的Brute-Force算法模式匹配过程 3.3.2 模式匹配应用 MyString类,replaceAll(pattern,s)改错。 【思考题3-4,实验题3-13】 以下算法在什么情况会出现怎样的错误?举例说明。怎样改正? //MyString类方法,返回将当前串中所有与pattern匹配的子串全部替换成str的字符串 public MyString replaceAll(MyString pattern,MyString str) { MyString temp = new MyString(this); //拷贝构造方法,复制当前串 int i=this.indexOf(pattern,0); while (i!=-1) { temp=temp.substring(0,i).concat(str).concat(temp.substring(i+pattern.length())); i=temp.indexOf(pattern,i+1); //从下个字符开始再次查找匹配子串 } return temp; } 【答】如果while中语句如下,若欲将\替换为\,上述算法会将作为替换串\中的\再次进行替换,导致死循环。 i=temp.indexOf(pattern, i); 如果while中语句如下,当pattern=\,str=\时,死循环。 i=temp.indexOf(pattern, i+1); 改正:将循环体中第3句改为如下,从替换子串的下一个字符开始 - 32 - ≠a