Go语言 排序与搜索切片

Python063

Go语言 排序与搜索切片,第1张

Go语言标准库中提供了sort包对整型,浮点型,字符切片进行排序,检查一个切片是否排好序,使用二分法搜索函数在一个有序切片中搜索一个元素等功能。

关于sort包内的函数说明与使用,请查看 https://godoc.org/sort

在这里简单讲几个sort包中常用的函数

在Go语言中,对字符串的排序都是按照字节排序,也就是说在对字符串排序时是区分大小写的。

二分搜索算法

Go语言中提供了一个使用二分搜索算法的sort.Search(size,fn)方法:每次只需要比较㏒₂n个元素,其中n为切片中元素的总数。

sort.Search(size,fn)函数接受两个参数:所处理的切片的长度和一个将目标元素与有序切片的元素相比较的函数,该函数是一个闭包,如果该有序切片是升序排列,那么在判断时使用 有序切片的元素 >= 目标元素。该函数返回一个int值,表示与目标元素相同的切片元素的索引。

在切片中查找出某个与目标字符串相同的元素索引

字符串比较是指按照字典次序对单个字符或字符串进行比较大小的操作,一般都是以ASCII码值的大小作为字符比较的标准。

在比较时,设置一个计数器,从零开始,一直循环到最短的那个字符结束,一位一位进行比较。

1.如果字符串1的第n位的ASCII码值等于字符串2的第n位的ASCII码值,则继续比较下一位。

2.如果字符串1的第n位的ASCII码值大于字符串2的第n位的ASCII码值,则输出结果:1,表示字符串1>字符串2。

3.如果字符串1的第n位的ASCII码值小于字符串2的第n位的ASCII码值,则输出结果:-1,表示字符串1<字符串2。

4.如果每一位的ASCII码值都相等,而且长度相同,则输出结果:0,表示字符串1==字符串2。

注意

(1) 在比较两个字符串时不能利用符号“==”,“==”符号比较的是两个字符串的地址是否相等。

(2) 若是比较两个字符,则可以用”==”直接进行比较。

(3) 但在比较两个string对象时是可以利用“==”的,相等的话,则表达式的返回值为1,不等为0。

两个字符串比较大小:

一、可以用compareTo()方法,另外还有compareToIgnoreCase(String)忽略大小写及compareTo(object string)这些方法返回值是int,以compareTo()方法为例:

1.如果字符串相等返回值为0,不等返回其他数值。

比较方法是先比较对应字符的大小(Ascall吗顺序),从第一个字母开始比较。

2.如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)

(负值前字符串的值小于后字符串,正值前字符串大于后字符串)

3.如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,

以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.

例如:

String s1="abc"

String s2="abcd"

String s3="abcdfg"

String s4="1bcdfg"

String s5="cdfg"

System.out.println(s1.compareTo(s2))//-1(前面相等,s1长度小1)

System.out.println(s1.compareTo(s3))//-3(前面相等,s1长度小3)

System.out.println(s1.compareTo(s4))//48("a"的ASCII码是97,"1"的的ASCII码是49,所以返回48)

System.out.println(s1.compareTo(s5))//-2("a"的ASCII码是97,"c"的ASCII码是99,所以返回-2)

二、还可以用“==”和.equals()方法判断大小:

1.“==”是一个判断相等的运算符,如果两边是基本数据类型,它判断的是值;如果两边是复合型数据类型(类类型),它判断的是地址;地址相同,内容一定相同,地址不同,内容不一定相同。

2..equals()方法只能判断复合型数据类型,由于继承Object类,默认判断的是两边在内存的地址,判断结果和“==”一样,但在一些其他的类库中equals()被重写,例如String,Integer,Data等类中有其自身的实现,比较内容就不是地址了。

例如:

String str1=new String("hello")

String str2="hello"

System.out.println("str1==str2:"+(str1==str2))\\false

System.out.println("str1.equals(str2):"+str1.equals(str2))\\true

当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。

但equals()在String中被重写过了,判断的是内容,不在是内存中的地址,所以是true。

但是String比较特殊,因为我们都知道jvm把内存分为3个区,分别是方法区,堆区和栈区。而在方法区中维护者一个String常量池,池中用来存放运行时产生的各种字符串,并且池中的内容不重复。而一般对象不在这个池中,对象放在堆里。这就需要分析String的创建方式:

1.当使用任何方式来创建一个字符串对象str=“X”时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串str,否则,不在池中添加。

2.Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。

3.使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

4.使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

例如:

String str2="hello"

String str3="hello"

System.out.println("str3==str2:"+(str3==str2))\\true

System.out.println("str3.equals(str2):"+str3.equals(str2))\\true

true的原因是hello都是从常量池中取出来的,但你new出来的不管常量池中有没有都会新建一个,地址就不一样了。

扩展资料:

string用法

1.string strs

生成空字符串

2.string s(str)

生成字符串str的复制品

3.string s(str,stridx)

将字符串str中始于stridx的部分作为构造函数的初值

4.string(str,strbegin,strlen)

将字符串str中始于strbegin,长度为strlen的部分作为字符串初值

5.string s(cstr)

以c_string类型cstr作为字符串s的初值

6.string s(cstr,char_len)

以c_string类型cstr的前char_len个字符作为字符串s的初值

7.string s(num,c)

生成一个字符串,包含num个c字符

8.string s(strs,beg,end)

以区间[beg,end]内的字符作为字符串s的初值

例子

#include&ltiostream&gt

#include&ltstring&gt

using namespace std

int main()

{

string str("12345678")

char ch[]="abcdefgh"

string a//定义一个空字符串

string str_1(str)//全部复制

string str_2(str,2,5)//从字符串str的第2个元素开始复制5个元素给str_2

string str_3(ch,5)//将字符串ch的前5个元素赋值给str_3

string str_4(5,'X')//将5个'X'组合赋值给str_4

string str_5(str.begin(),str.end())//复制str所有元素给str_5

cout&lt&ltstr&lt&ltendl

cout&lt&lta&lt&ltendl

cout&lt&ltstr_1&lt&ltendl

cout&lt&ltstr_2&lt&ltendl

cout&lt&ltstr_3&lt&ltendl

cout&lt&ltstr_4&lt&ltendl

cout&lt&ltstr_5&lt&ltendl

return 0

}