比如给定一个字符串数组,“”,“ab”,"ab","","","","xx","yy","zz",查找ab字符串最左边的位置就是1,而不是2。
如果要找的字符串是空,或者根本没有找到,就返回-1
思路采用二分法,但是这里和普通二分不同,要进行判断
设要找的字符串为str,start=0,end等于字符串数组最后一个位置
如果当前mid处值等于要找的,这时候传给全局变量Pos,但是这个pos并非最终结果,因为很有可能他的左边,还有要找的字符串,所以要把end设为mid-1.
如果当前mid处值不等于要找的,这里有两个情况
一个是等于空串,这时候要从空串处从右到左遍历,如果遍历到最终,还是没有找到非空,肯定是返回-1了
如果找到了非空串,还要分三种情况判断
一种是等于要找的字符串,这时候就把位置付给全局变量pos
一种是小于要找的字符串,证明要找的字符串一定在右半区间,左半区间已经不用找了,start赋值为mid+1
一种是大于要找的字符串,这时候证明要找的肯定在其左边,end赋值为其下标-1。
一种是不等于空串,这样就按照普通二分来处理,大于要找的,就在左半区间找,小于要找的,就在右半区间找。
代码如下
#include <iostream>
#include <string>
using namespace std;
int FindString(string a[10],string str,int n)
{
int start=0,end=n-1;
int mid=(start+end)/2;
int pos=-1;
bool bContinue=false;
if(str=="")
return -1;
while(start<=end)
{
int mid=(start+end)/2;
if(a[mid]==str)
{
pos=mid;
end=mid-1;
}
else if(a[mid]!=str)
{
if(a[mid]!="")
{
if(a[mid]<str)
start=mid+1;
else
end=mid-1;
}
else
{
for(int k=mid-1;k>=start;k--)
{
if(a[k]!="")
{
if(a[k]<str)
start=mid+1;
else if(a[k]>str)
end=k-1;
else
{
pos=k;
end=k-1;
}
bContinue=true;
break;
}
}
if(!bContinue)
return -1;
else
{
bContinue=false;
}
}
}
}
return pos;
}
int main()
{
string a[]={"pp","de","cd","de","de","","","eg"};
cout<<FindString(a,"de",sizeof(a)/sizeof(a[0]));
return 0;
}