数据结构(Java版)-习题解答与实验指导 下载本文

内容发布更新时间 : 2024/5/16 17:35:59星期一 下面是文章的全部内容请认真阅读。

{

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='0' && s.charAt(dot)<='9') //获得小数部分值

{ 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