程序员面试金典: 9.11 排序与查找 11.5有个排序后的字符串数组,其中散布这一些空字符串,编写一个方法,找出给定字符串的位置

来源:互联网 发布:js实现文件下载功能 编辑:程序博客网 时间:2024/06/05 22:30
#include <iostream>#include <stdio.h>#include <vector>#include <string>using namespace std;/*问题:有个排序后的字符串数组,其中散布这一些空字符串,编写一个方法,找出给定字符串的位置分析:题目的意思应该是字符串数组已经排好序,但是里面混杂着空字符串,例如:      ["ab" , " " , "ba" , " " , "ma"]  最简单的方式是暴力破解:遍历所有,顺序查找,时间复杂度为O(N)  另外一种方式就是:把所有字符串拼接成一个大的字符串:变成"ab ba ma",比如要查找"ba",  问题变成了字符串查找,字符串查找时间复杂度为O(N)的KMP算法书上解法:早就应该想到,既然是搜索,肯定要跟二分搜索扯上关系。注意排好序的字符串,可以用          二分查找,可以用待查找的字符串str和中间字符串进行比较,如果遇到空字符串,就将中间  位置移动到距离其最近的非空字符串;如果距离两边的非空字符串一样近,就先右边,后左边,  如果找不到,继续寻找中间位置输入:6(字符串个数) ba(待查找的字符串)ab #(表示空字符串) # ba # ma6 chaoab # # ba # ma输出:3(待查找字符串下标,找不到返回-1)-1*/const string EMPTY_STRING = "#";int binarySearch(vector<string>& datas , int low , int high , string& value){if(datas.empty() || low < 0 || high < 0 || value.empty()){return  -1;}//如果找不到,返回-1if(low > high){return -1;}int middle = low + (high - low)/2;int left;int right;//如果中间字符串是空字符串,需要寻找到左右两侧中距离其最近的非空字符串,然后用二分查找if(datas.at(middle).empty()){left = middle - 1;right = middle + 1;while(left >= low && right <= high){//右侧字符串不空if(!datas.at(right).empty()){middle = right;break;}else if(!datas.at(left).empty()){middle = left;break;}else{left--;right++;}}}//找到位置后,下面用二分查找int result = -1;if(datas.at(middle) == value){return middle;}//比较两个字符串,如果:查找字符串 < 中间字符串,即strcmp < 0,说明在左侧 else if( strcmp( value.c_str() , datas.at(middle).c_str() ) < 0 ){result = binarySearch(datas , low , middle - 1 ,value);return result;}else{result = binarySearch(datas, middle + 1 , high , value);return result;}}void process(){int n;vector<string> strings;string value;string searchValue;while(cin >> n >> searchValue){strings.clear();for(int i = 0 ; i < n ; i++){cin >> value;if(value != EMPTY_STRING){strings.push_back(value);}else{strings.push_back("");}}//下面就开始寻找int result = binarySearch(strings , 0 , strings.size() - 1 , searchValue);cout << result << endl;}}int main(int argc, char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击