- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Lexicographic rank of a string among all its substrings
String manipulation is an essential topic in computer science that involves operations such as concatenation, substring, reversing, and more. One interesting problem related to string manipulation is to find the lexicographic rank of a string among all its substrings. In this article, we will discuss an algorithm to solve this problem using recursion and backtracking.
Problem Statement
Given a string S of length N, we have to find the lexicographic rank of S among all its substrings. The lexicographic rank is defined as the position of a string in the lexicographically sorted list of all its substrings.
Approach
We can solve this problem using a recursive and backtracking approach. We will generate all possible substrings of the given string S and keep track of the number of substrings that come before S in lexicographic order.
Let's see the algorithm in detail −
Initialize a variable "rank" to 1.
Generate all possible substrings of the given string S using recursion and backtracking.
For each substring, compare it with the given string S and increment the "rank" variable if the substring comes before S in lexicographic order.
Return the "rank" variable.
Example
Here're the codes to implement the above algorithm −
#include <stdio.h> #include <string.h> // Function to generate all substrings and find their lexicographic rank void generateSubstrings(const char* s, char* temp, int start, int end, int* rank) { if (start > end) { if (strcmp(temp, s) < 0) { (*rank)++; } return; } generateSubstrings(s, temp, start + 1, end, rank); char new_temp[end - start + 2]; strncpy(new_temp, temp, start); new_temp[start] = s[start]; new_temp[start + 1] = '\0'; generateSubstrings(s, new_temp, start + 1, end, rank); } // Function to find the lexicographic rank of a string int lexicographicRank(const char* s) { int rank = 1; generateSubstrings(s, "", 0, strlen(s) - 1, &rank); return rank; } int main() { const char* s = "abc"; printf("String: %s\n", s); printf("Lexicographic Rank: %d\n", lexicographicRank(s)); return 0; }
Output
String: abc Lexicographic Rank: 8
#include <iostream> #include <string> #include <algorithm> using namespace std; void generateSubstrings(string s, string temp, int start, int end, int& rank) { if (start > end) { if (temp < s) { rank++; } return; } generateSubstrings(s, temp, start + 1, end, rank); generateSubstrings(s, temp + s[start], start + 1, end, rank); } int lexicographicRank(string s) { int rank = 1; generateSubstrings(s, "", 0, s.length() - 1, rank); return rank; } int main() { string s = "abc"; cout << "String: " << s << endl; cout << "Lexicographic Rank: " << lexicographicRank(s) << endl; return 0; }
Output
String: abc Lexicographic Rank: 4
public class Main { // Function to generate all substrings and find their lexicographic rank static void generateSubstrings(String s, StringBuilder temp, int start, int end, int[] rank) { if (start > end) { if (temp.toString().compareTo(s) < 0) { rank[0]++; } return; } generateSubstrings(s, temp, start + 1, end, rank); temp.append(s.charAt(start)); generateSubstrings(s, temp, start + 1, end, rank); temp.setLength(temp.length() - 1); // Remove the last character from temp } // Function to find the lexicographic rank of a string static int lexicographicRank(String s) { int[] rank = {1}; generateSubstrings(s, new StringBuilder(), 0, s.length() - 1, rank); return rank[0]; } public static void main(String[] args) { String s = "abc"; System.out.println("String: " + s); System.out.println("Lexicographic Rank: " + lexicographicRank(s)); } }
Output
String: abc Lexicographic Rank: 4
def generate_substrings(s, temp, start, end, rank): if start > end: if temp < s: rank[0] += 1 return generate_substrings(s, temp, start + 1, end, rank) generate_substrings(s, temp + s[start], start + 1, end, rank) def lexicographic_rank(s): rank = [1] generate_substrings(s, "", 0, len(s) - 1, rank) return rank[0] if __name__ == "__main__": s = "abc" print("String:", s) print("Lexicographic Rank:", lexicographic_rank(s))
Output
String: abc Lexicographic Rank: 4
Explanation of Test Case
Let's take the string "abc" as an example. We need to find the lexicographic rank of all its substrings.
Initially, we have an empty string, which has a lexicographic rank of 1.
The substring "a" has a lexicographic rank of 1, as it is the first substring in lexicographic order.
The substring "ab" has a lexicographic rank of 2, as it comes after "a" in lexicographic order.
The substring "abc" has a lexicographic rank of 4, as it comes after "a", "ab", and "ac" in lexicographic order.
The substring "b" has a lexicographic rank of 3, as it comes after "a" but before "c" in lexicographic order.
The substring "bc" has a lexicographic rank of 5, as it comes after "ab" and "ac" but before "c" in lexicographic order.
The substring "c" has a lexicographic rank of 6, as it comes after "a", "ab", "ac", and "b" in lexicographic order.
Therefore, the lexicographic rank of all substrings of "abc" is: [1, 1, 2, 3, 4, 5, 6].
Conclusion
In this article, we have discussed an algorithm to find the lexicographic rank of a string among all its substrings using recursion and backtracking. This approach can be used to solve other problems related to string manipulation as well.
To Continue Learning Please Login
Login with Google