首页 > 代码库 > 【语言对比】字符串

【语言对比】字符串

    字符串是各类语言中一种非常重要的数据结构,事实上大部分的代码都是基于字符串的操作,各个语言对字符串的处理方式,也是我们评价各个语言的一个重要方面。


    因为C++库中并没有提供字符串这个数据类型,所以我们以STL中提供的string来进行对比。这里不选择char*进行对比,是因为char*在功能上和其它两种语言差距实在是太大了,基本上不具有对比性,之前一直使用的都是STL,所以这里直接选用STL来对比了。   

   JAVA中选用String及其周边类,它们会作为一个整体进行对比;

   而python中的string是一个内置的数据类型,直接用于对比。


1、存储的方式

   在STL中string类实现中,是直接申请内容空间,来存放对应的char数组,但是string类自身接管了这些内存的生命周期,不需要开发者做处理;在JAVA中String类的实现,也是通过char[]来存储字符串内容,JAVA中所有对象的生命周期,都是有虚拟机来管理的,同样不需要开发者对其做处理;在Python中,String本身就是一种基本的数据类型,不需要靠其他的数据类型来对其进行存储


2、支持的操作

   以Python为标准,对比在字符串操作上几种语言的异同。

功能描述PythonJavaSTL
是否包含子串

str1 in str;

2str1 not in str2;

str2.contains(str1);


str2.find(str1)
字符串相加
str1+str2str1+str2str1+str2
倍数复制str1*2不支持
不支持
下标取值
str1[0]不支持str1[0]
下标范围取值

str1[0:2];

str1[0:5:2]

不支持不支持
取字符串长度len(str1)str1.length()

str1.length();

str1.size()

去最小/大字符

min(str1);

max(str1)

不支持不支持
获取子串出现的第一个位置

str1.index(str2);

str1.find(str2);

str1.find(str2,5,10)

str1.rfind(str2)
str1.rindex(str2)

str1.indexOf(str2);

str1.indexOf(str2,10);

str2.lastIndexOf(str2)

str2.find(str1);

str2.find(str1,10)

str2.rfind(str1)

获取子串出现的次数

str1.count(str2);

str1.count(str2,10,15)

不支持不支持
字符串首字母大写,其他字母小写
str1.capitalize()
不支持不支持
字符串居中显示,其它用指定字符填充

str1.center(80,"*")

str1.ljust(4,"*")

str1.rjust(4,"*")

str1.zfill(4)

不支持不支持
是否以某子串结尾

str1.endswith(str2

)

str1.startwith(str2)

str1.endsWith(str2)
不支持
把tab转换为空格
str1.expandtabs(4)不支持不支持
格式化字符串
str1.format(str2)String.format(str1,str2,d1)不支持,需要借用sprintf
是否仅是字符\数字

str1.isalnum()

str1.isalpha()

str1.isdigit()

不支持不支持,系统提供isalnum(c),isalpha(c),isdigit(c),仅能判断单个字符;
是否全是大写/小写

str1.islower()

str1.isupper()

不支持不支持,系统提供islower(c),isupper(c),仅能判断单个字符
是否是空格str1.isspace()不支持不支持,系统提供isspace(c),仅能判断单个字符
是否是标题:即只有单词首字母大写

str1.istitle()

str1.title()

不支持不支持
以自身为分隔符,把list中的内容连接起来,返回一个String
str1.join(l1)不支持不支持
转换为小写

str1.lower()

str1.swapcase()

str1.upper()

str1.toLowCase()不支持
去掉开头的指定字符

str1.lstrip("abc"

)

str1.rstrip("123")

str1.strip(str2)

不支持

不支持
字符串拆分

str1.partition("str2")

str1.rpartition("str2")

str1.split("str2")

str1.rsplit("str2")

str1.split(str2)不支持
字符串替换
str1.replace("old","new")

str1.replaceAll(regex,new)

str1.replace(regex,new)

str1.replaceFirst(regex,new)

str1.replace()
字符串复杂替换str1.translate不支持不支持


















3、对汉字的支持(有关字符集的处理)

    在STL中,对string的处理是不带任何编码方式的,仅仅是保存对应的char的取值。假如中文的“你好”,当前采用UTF-8进行编码,取值为“E4 BD A0 E5 A5 BD”,那么通过string保存的内容的取值即为“E4 BD A0 E5 A5 BD”,如果我们想正常的把这部分内容读取出来,那我们首先要知道它是以UTF-8的方式进行存储的,必须要按照UTF-8的方式,进行解码。

    而在java中,String类统一存储的是字符的unicode编码,“你好”对应的unicode编码为“4F 60 59 7D”,这个才是真正存储在String的char数组中的内容。JAVA中采用unicode对所有字符统一编码,正好和其char的长度为2个字节对应,因为unicode中所有字符都是用2个字节来进行编码的。当我们往String中赋值的时候,JAVA会根据当前字符对应的编码方式,转换为unicode进行存储;当我们从String中获取内容时,JAVA会根据需要的编码方式,把转换后的结果返回给我们。从入到出,始终是有一个编码的转换过程。即使在获取bytes的时候,没有指定编码方式,并不意味着取出来的是unicode编码方式,而是意味着以java虚拟机默认的编码方式获取。所以,对于涉及到中文的操作,最好能够指定相应的编码,以免在运行时因为环境的不同而出错。

    Python中的string对象,和C++中一样,并不对存储的内容做特殊的编码转换,什么样编码方式存入,就得以同样正确的编码方式读取出来。这样的实现,存在的问题是显而易见的。我们对于字符串的读取,是基于字节的,而不是真正基于字符的。如果存储的是中文,很有可能读取出来的结果就是半个字符,非常不利于进行字符的操作。所以,Python从2.0开始,增加了ustring的支持,也就是说,python默认这种string中存储的是unicode编码的字符串,每两个字节,代表一个字符,基于字符的操作,也是以两个字节为单位的,由此就不会出现半个字符的问题。但是,和JAVA强制的内在转换不同,Python并不对其进行转换,开发者自己保存标识为ustring的内容,的确是unicode编码的,如果不是,那么处理的结果就是乱码。例如,当开发者获取到以UTF8方式编码的字符串时,首先,要调用unicode(str,"utf8")把其转换为unicode string,经过处理后,再把处理后的unicode string通过encode("utf8")转换为utf8的方式存储或者是发送出去。当然,如果你对字符的操作不涉及截取、查找等,直接用普通的string存储,不经过编解码的转换,也没有太大问题。从这里可以看出来,python其实是集合了c++和java的处理,采取了一个较为折中的方式。


4、和数值的相互转换

    Python中的数据类型只有整数和浮点数这两种,从string转换为int或者是float时,通过int、float系统函数,进行转换即可。而从int、float转化为string,只需要通过str函数进行转换即可

    int -> float/string   a=123   b=float(a)  c=str(a)

    float -> int/string   a=123.5 b=int(a) c=str(a)

    string ->int/float    a="123.3" b=int(a) c=float(a)

    

    C++中的数据类型转换:


    JAVA中的数据类型转换:JAVA为String提供了valueOf函数,支持所有数据对象转换为String;而针对每一种数据类型,都提供的parse函数,把String转换为对应的数据类型。

    int  a = 123;

    float b = 123.3f;

    String a1 = String.valueOf(a);

    String b1 = String.valueOf(b);

    int a2 = Integer.parseInt(a1);

    float b2 = Float.parseFloat(b1);



本文出自 “星光” 博客,请务必保留此出处http://galaxyflower.blog.51cto.com/9006676/1529715