字符串学习(1)

来源:互联网 发布:java高并发优化 编辑:程序博客网 时间:2024/06/05 09:53

1、串可以用顺序存储,也可以用链式存储。STL中,vector为顺序,list为链式。

空串是不含任何字符的串,即空串的长度为0. String str=””;

空格串是由空格组成的串,其长度等于空格的个数。String str=” “;

 

2

char s[ ]=”\\123456\123456\t”;

printf(“%d\n’,strlen(s));

输出结果为12

分析:首先strlen不包括结束标识符“\n”,只计算字符数组长度。此处有3个转义字符分别为“\\”、“\123”、”\t”,即“\”、“S”、“tab”。

\123,在ascii中,‘\ddd’表示八进制,而‘\xdd’表示十六进制,(d是一个数字占位符,x表示十六进制),所以\123的十进制为83,在ascii中对应的是S.

 

char s[ ]=”//123456//123456/t”;

printf(“%d\n’,strlen(s));

若是这个形式的话,打印出来的将会输出17。

 

3n个字符构成的一个字符串,所以字母不同,求有多少子串?

 求子串:n+(n-1)+(n-2)+……+1=n(n+1)/2;再加上一个空串;

所以共有子串n(n+1)/2+1;

 

若是考虑真子串的话,应该是n(n+1)/2-1;

 

4int fun(char *x)

      {

      char*y=x;//定义y指针指向x指针指向的字符串,此时x与y指针地址相同

      while(*y++);//当*y!=’\0’时,指针指向字符串的下一位,直到*y==’\0’,由于此时还会执行++操作,所以y指针指向字符串末尾结束符的下一位,即此时y已经移到了字符串长度+1位;

      return(y-x-1);//即字符串的长度

}

//函数表示求字符串长度

 

5、已知S=”aaab”,Next数组值为 0123

next值过程:

前两位:next数组值前两位一定为01,即aaab中的前两位对应01;

第三位:3a前面是2a(2a表示序号为2的a),2a的next数组值为1,将2a和1a相比,两者相同都是a,则3a的next值为2a的next值加1,即1+1=2;

第四位:4b前3a的next值为2,3a与2a比较,二者相同,则其next值为2a的next值+1,即2+1=3,所以第四位为3.

综上所述,Next数组值为0123;

 

如果比较的时候碰到与前一位字符不同,那就以前一位的next值为序号,找到这个序号对应的字符,在进行比较,如果与之相同,就用这一位的next值+1,如果不同就继续重复这个操作直到找到相同的字符为止。如果一直重复到第一位还找不到,则将所求位的next值置为1.

 

6、字符串www.qq.com所有非空子串(两个子串如果内容相同则算一个)个数是50.

分析:该字符串有10个字符,所以有子串10+9……+1=55,但是有重复子串(w、q、.),需要减去2个w,1个ww,1个q,1个.,所以共有55-5-50个非空子串。

 

补充:子串是从原字符串中连续截取得到;子序列则不要求连续,即可以是离散截取。

若是求子序列,那么应该是有1018.因为有10个字符,应该是2^10=1024个子序列,减去一个空串,再减去5个重复子序列,即1024-6=1018个不重复的子序列。

 

7.中缀表达式(a+b)*c*(d-e/f)转成后缀表达式: ab+c*def/-*

后缀表达式是卢卡西维奇发明的一种表达式方法,这种表示方式把运算符写在运算对象后面。Eg:a+b写成ab+,所以也称后缀式。

这种表示法优点是根据运算对象和运算符出现次序进行计算,不需要使用括号,也便于用机械实现求值。

 

8、多型数据类型:数据元素的类型不确定,字符串的每个元素始终都是字符char,而不会是别的类型。而栈就可以是整数栈,字符栈,对象栈。

 

9、模式匹配:数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串。

10KMP算法下,长为n的字符串中匹配长度为m的子串的复杂度:O(m+n);

分析:KMP算法通过提前处理出的next数组,在发生不匹配时直接跳过下一个可能符合的位置,而不是一个个去遍历比较,时间复杂度为O(m+n)。

KMP算法关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度为O(m+n)。

 

11、某字符串满足:

concat(head(s),head(tail(tail(s))))=”ac”,(head,tail的定义等同广义表),则s=accc

分析:广义表L=(A,B,C),表头是A,表尾(B,C),这是定义。

tail()表示取字符串的尾部,head()表示取字符串的头,concat()表示字符串拼接。取两次尾部一次头部,然后合并,即为accc。

 

12、用二进制来编码字符串“abcdabaa,需要能够根据编码,解码回原来的字符串,最少需要(14)长的二进制字符串;

分析:对abcd进行Huffman编码,根据权值建立Huffman树,得到最优编码;a=0,b=10,c=110,d=111,然后再数一下即可。

Huffman编码不是唯一的,a:1位,b:2位,c:3位,d:3位;所以4*1+2*2+3+3=14;

 

13Huffman就是求最优解,可以有多套方案,但最终每套方案生成的编码长度都相同且都是最优解。

不同方案获得的编码值是不同的,但每个字符的编码长度是固定的。

不同方案影响的只是通向节点的路径为0还是1,而不会影响Huffman树的层次结构。

生成了Huffman树之后,出现频率越高的节点越靠近根,深度越小即编码值尾数越短;出现的频率越低的节点越远离根,深度越大即编码位数越长。

 

14String str=new String(“abc”),”abc”在内存中是怎么分配的?

堆与字符串常量区。

字符串常量池:JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存成为字符串常量池或者字符串字面量池。

 

Java中所以由类实例化的对象和数组都存放在堆内存中,无论是成员变量 ,局部变量,还是类变量,它们指向的对象都存放在堆内存中。

栈内存用来存储局部变量和方法调用。

0 0