Given an array of strings. The array has both empty and non-empty strings. All non-empty strings are in sorted order. Empty strings can be present anywhere between non-empty strings.
Examples:
Input : arr[] = {"for", "", "", "", "geeks",
"ide", "", "practice", "" ,
"", "quiz", "", ""};
str = "quiz"
Output : 10
The string "quiz" is present at index 10 in
given array.
A simple solution is to linearly search given str in array of strings.
A better solution is to do modified Binary Search. Like normal binary search, we compare given str with middle string. If middle string is empty, we find the closest non-empty string x (by linearly searching on both sides). Once we find x, we do standard binary search, i.e., we compare given str with x. If str is same as x, we return index of x. if str is greater, we recur for right half, else we recur for left half.
Below is the implementation of the idea:
C++
#include <bits/stdc++.h>
using namespace std;
int compareStrings(string str1, string str2)
{
int i = 0;
while (str1[i] == str2[i] && str1[i] != '\0' )
i++;
if (str1[i] > str2[i])
return -1;
return (str1[i] < str2[i]);
}
int searchStr(string arr[], string str, int first,
int last)
{
if (first > last)
return -1;
int mid = (last+first)/2;
if (arr[mid].empty())
{
int left = mid - 1;
int right = mid + 1;
while ( true )
{
if (left < first && right > last)
return -1;
if (right<=last && !arr[right].empty())
{
mid = right;
break ;
}
if (left>=first && !arr[left].empty())
{
mid = left;
break ;
}
right++;
left--;
}
}
if (compareStrings(str, arr[mid]) == 0)
return mid;
if (compareStrings(str, arr[mid]) < 0)
return searchStr(arr, str, mid+1, last);
return searchStr(arr, str, first, mid-1);
}
int main()
{
string arr[] = { "for" , "" , "" , "" , "geeks" , "ide" , "" ,
"practice" , "" , "" , "quiz" , "" , "" };
string str = "quiz" ;
int n = sizeof (arr)/ sizeof (arr[0]);
cout << searchStr(arr, str, 0, n-1);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int compareStrings(String str1,
String str2)
{
int i = 0 ;
while (i < str1.length() - 1 &&
str1.charAt(i) == str2.charAt(i))
i++;
if (str1.charAt(i) > str2.charAt(i))
return - 1 ;
if (str1.charAt(i) < str2.charAt(i))
return 1 ;
else
return 0 ;
}
static int searchStr(String[] arr, String str,
int first, int last)
{
if (first > last)
return - 1 ;
int mid = (last + first) / 2 ;
if (arr[mid].isEmpty())
{
int left = mid - 1 ;
int right = mid + 1 ;
while ( true )
{
if (left < first && right > last)
return - 1 ;
if (right <= last && !arr[right].isEmpty())
{
mid = right;
break ;
}
if (left >= first && !arr[left].isEmpty())
{
mid = left;
break ;
}
right++;
left--;
}
}
if (compareStrings(str, arr[mid]) == 0 )
return mid;
if (compareStrings(str, arr[mid]) < 0 )
return searchStr(arr, str, mid + 1 , last);
return searchStr(arr, str, first, mid - 1 );
}
public static void main(String[] args)
{
String[] arr = { "for" , "" , "" , "" , "geeks" ,
"ide" , "" , "practice" , "" ,
"" , "quiz" , "" , "" };
String str = "quiz" ;
int n = arr.length;
System.out.println(searchStr(arr, str, 0 , n - 1 ));
}
}
|
Python3
def compareStrings(str1, str2):
i = 0
while i < len (str1) - 1 and str1[i] = = str2[i]:
i + = 1
if str1[i] > str2[i]:
return - 1
return str1[i] < str2[i]
def searchStr(arr, string, first, last):
if first > last:
return - 1
mid = (last + first) / / 2
if len (arr[mid]) = = 0 :
left, right = mid - 1 , mid + 1
while True :
if left < first and right > last:
return - 1
if right < = last and len (arr[right]) ! = 0 :
mid = right
break
if left > = first and len (arr[left]) ! = 0 :
mid = left
break
right + = 1
left - = 1
if compareStrings(string, arr[mid]) = = 0 :
return mid
if compareStrings(string, arr[mid]) < 0 :
return searchStr(arr, string, mid + 1 , last)
return searchStr(arr, string, first, mid - 1 )
if __name__ = = "__main__" :
arr = [ "for" , " ", " ", " ", " geeks ", " ide ", " ",
"practice" , " " , " ", " quiz ", " ", " "]
string = "quiz"
n = len (arr)
print (searchStr(arr, string, 0 , n - 1 ))
|
C#
using System;
public class GFG
{
static int compareStrings(String str1, String str2)
{
int i = 0;
while (i < str1.Length - 1 && str1[i] == str2[i])
i++;
if (str1[i] > str2[i])
return -1;
if (str1[i] < str2[i])
return 1;
else
return 0;
}
static int searchStr(String[] arr, String str, int first, int last)
{
if (first > last)
return -1;
int mid = (last + first) / 2;
if (arr[mid] == "" )
{
int left = mid - 1;
int right = mid + 1;
while ( true )
{
if (left < first && right > last)
return -1;
if (right <= last && !(arr[right] == "" ))
{
mid = right;
break ;
}
if (left >= first && !(arr[left] == "" ))
{
mid = left;
break ;
}
right++;
left--;
}
}
if (compareStrings(str, arr[mid]) == 0)
return mid;
if (compareStrings(str, arr[mid]) < 0)
return searchStr(arr, str, mid + 1, last);
return searchStr(arr, str, first, mid - 1);
}
public static void Main( string [] args)
{
String[] arr = { "for" , "" , "" , "" , "geeks" , "ide" , "" , "practice" , "" , "" , "quiz" , "" , "" };
String str = "quiz" ;
int n = arr.Length;
Console.WriteLine (searchStr(arr, str, 0, n - 1));
}
}
|
Javascript
<script>
function compareStrings(str1, str2)
{
let i = 0;
while (i < str1.length - 1 &&
str1[i] == str2[i])
i++;
if (str1[i] > str2[i])
return -1;
if (str1[i] < str2[i])
return 1;
else
return 0;
}
function searchStr(arr, str, first, last)
{
if (first > last)
return -1;
let mid = parseInt((last + first) / 2, 10);
if (arr[mid] == "" )
{
let left = mid - 1;
let right = mid + 1;
while ( true )
{
if (left < right && right > last)
return -1;
if (right <= last && arr[right] != "" )
{
mid = right;
break ;
}
if (left >= right && !arr[left] == "" )
{
mid = left;
break ;
}
right++;
left--;
}
}
if (compareStrings(str, arr[mid]) == 0)
return mid;
if (compareStrings(str, arr[mid]) < 0)
return searchStr(arr, str, mid + 1, last);
return searchStr(arr, str, first, mid - 1);
}
let arr = [ "for" , "" , "" , "" , "geeks" ,
"ide" , "" , "practice" , "" ,
"" , "quiz" , "" , "" ];
let str = "quiz" ;
let n = arr.length;
document.write(searchStr(arr, str, 0, n - 1));
</script>
|
Output:
10
Using linear search would take us O(L*N), where L is the string comparison. To optimize the runtime, we use binary search making the time complexity O(L(logN)).
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!