Search in an array of strings where non-empty strings are sorted

14 Sep, 2021
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++
Java
Python3
Javascript
// C++ program to find location of a str in// an array of strings which is sorted and// has empty strings between strings.#include <bits/stdc++.h>using namespace std; // Compare two string equals are notint 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]);} // Main function to find string locationint searchStr(string arr[], string str, int first,                                        int last){    if (first > last)        return -1;     // Move mid to the middle    int mid = (last+first)/2;     // If mid is empty , find closest non-empty string    if (arr[mid].empty())    {        // If mid is empty, search in both sides of mid        // and find the closest non-empty string, and        // set mid accordingly.        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 str is found at mid    if (compareStrings(str, arr[mid]) == 0)        return mid;     // If str is greater than mid    if (compareStrings(str, arr[mid]) < 0)        return searchStr(arr, str, mid+1, last);     // If str is smaller than mid    return searchStr(arr, str, first, mid-1);} // Driver Codeint main(){    // Input arr of Strings.    string arr[] = {"for", "", "", "", "geeks", "ide", "",                     "practice", "" , "", "quiz", "", ""};     // input Search String    string str = "quiz";    int n = sizeof(arr)/sizeof(arr[0]);     cout << searchStr(arr, str, 0, n-1);    return 0;}
// Java program to find location of a str in// an array of strings which is sorted and// has empty strings between strings.import java.util.*; class GFG{     // Compare two string equals are not    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;    }     // Main function to find string location    static int searchStr(String[] arr, String str,                            int first, int last)    {        if (first > last)            return -1;         // Move mid to the middle        int mid = (last + first) / 2;         // If mid is empty,        // find closest non-empty string        if (arr[mid].isEmpty())        {             // If mid is empty, search in both sides of mid            // and find the closest non-empty string, and            // set mid accordingly.            int left = mid - 1;            int right = mid + 1;            while (true)            {                if (left < right && right > last)                    return -1;                if (right <= last && !arr[right].isEmpty())                {                    mid = right;                    break;                }                if (left >= right && !arr[left].isEmpty())                {                    mid = left;                    break;                }                right++;                left--;            }        }         // If str is found at mid        if (compareStrings(str, arr[mid]) == 0)            return mid;         // If str is greater than mid        if (compareStrings(str, arr[mid]) < 0)            return searchStr(arr, str, mid + 1, last);         // If str is smaller than mid        return searchStr(arr, str, first, mid - 1);    }     // Driver Code    public static void main(String[] args)    {         // Input arr of Strings.        String[] arr = { "for", "", "", "", "geeks",                         "ide", "", "practice", "",                         "", "quiz", "", "" };         // input Search String        String str = "quiz";        int n = arr.length;         System.out.println(searchStr(arr, str, 0, n - 1));    }} // This code is contributed by// sanjeev2552
# Python3 program to find the location of# an str in an array of strings which is sorted# and has empty strings between strings. # Compare two string equals are notdef 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]  # Main function to find string locationdef searchStr(arr, string, first, last):      if first > last:        return -1     # Move mid to the middle    mid = (last + first) // 2     # If mid is empty , find closest non-empty string    if len(arr[mid]) == 0:              # If mid is empty, search in both sides of mid        # and find the closest non-empty string, and        # set mid accordingly.        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 str is found at mid    if compareStrings(string, arr[mid]) == 0:        return mid     # If str is greater than mid    if compareStrings(string, arr[mid]) < 0:        return searchStr(arr, string, mid+1, last)     # If str is smaller than mid    return searchStr(arr, string, first, mid-1)  # Driver Codeif __name__ == "__main__":      # Input arr of Strings.    arr = ["for", "", "", "", "geeks", "ide", "",                    "practice", "" , "", "quiz", "", ""]     # input Search String    string = "quiz"    n = len(arr)     print(searchStr(arr, string, 0, n-1))     # This code is contributed by Rituraj Jain
<script>    // Javascript program to find location of a str in    // an array of strings which is sorted and    // has empty strings between strings.         // Compare two string equals are not    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;    }      // Main function to find string location    function searchStr(arr, str, first, last)    {        if (first > last)            return -1;          // Move mid to the middle        let mid = parseInt((last + first) / 2, 10);          // If mid is empty,        // find closest non-empty string        if (arr[mid] == "")        {              // If mid is empty, search in both sides of mid            // and find the closest non-empty string, and            // set mid accordingly.            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 str is found at mid        if (compareStrings(str, arr[mid]) == 0)            return mid;          // If str is greater than mid        if (compareStrings(str, arr[mid]) < 0)            return searchStr(arr, str, mid + 1, last);          // If str is smaller than mid        return searchStr(arr, str, first, mid - 1);    }         // Input arr of Strings.    let arr = [ "for", "", "", "", "geeks",                    "ide", "", "practice", "",                    "", "quiz", "", "" ];     // input Search String    let str = "quiz";    let n = arr.length;     document.write(searchStr(arr, str, 0, n - 1)); // This code is contributed by vaibhavrabadiya3.</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)). 
This article is contributed by Mr. Somesh Awasthi. 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. 
rituraj_jain
sanjeev2552
azadug
vaibhavrabadiya3
arorakashish0911
Binary Search
Searching
Strings
Searching
Strings
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Binary Search
Maximum and minimum of an array using minimum number of comparisons
Linear Search
K'th Smallest/Largest Element in Unsorted Array | Set 1
Search an element in a sorted and rotated array
Write a program to reverse an array or string
Reverse a string in Java
Write a program to print all permutations of a given string
C++ Data Types
Check for Balanced Brackets in an expression (well-formedness) using Stack