public static String getMiddleString(String S, String T)
{
if(S.length()<T.length()){
for(int i=0;i<(T.length()-S.length());i++)S = '`'+S;
}
if(T.length()<S.length()){
for(int i=0;i<(S.length()-T.length());i++)T = '`'+T;
}
int N = S.length();
// Stores the base 26 digits after addition
int[] a1 = new int[N + 1];
for (int i = 0; i < N; i++) {
a1[i + 1] = (int)S.charAt(i) - 97
+ (int)T.charAt(i) - 97;
}
// Iterate from right to left
// and add carry to next position
for (int i = N; i >= 1; i--) {
a1[i - 1] += (int)a1[i] / 26;
a1[i] %= 26;
}
// Reduce the number to find the middle
// string by dividing each position by 2
for (int i = 0; i <= N; i++) {
// If current value is odd,
// carry 26 to the next index value
if ((a1[i] & 1) != 0) {
if (i + 1 <= N) {
a1[i + 1] += 26;
}
}
a1[i] = (int)a1[i] / 2;
}
String result ="";
for (int i = 1; i <= N; i++) {
result+=(char)(a1[i] + 97);
}
return result;
}
This is code that I took from https://www.geeksforgeeks.org/find-the-string-present-at-the-middle-of-a-lexicographically-increasing-sequence-of-strings-from-s-to-t/ to help me find the string in the middle between 2 strings in lexicographical order (e.g. the middle string between "z" and "ad" is "ab". The idea is that it treats the strings as base-26 numbers and gets the number in the middle of them and changes it back to a string.The code from the blog only works with same length strings, so I modified it and it seems to work but I'm not exactly sure why and I'm also not sure if it would work with all cases, I would appreciate it if someone would explain why my modification is correct or incorrect.
The modification was the 2 if conditions on top, it basically prefixes the smaller string with "`" characters (ASCII=96). Initially I tried prefixing with "a", but that didn't work, so I thought of trying the character just before "a" in ASCII.
In my case when I talk about lexicographical ordering I mean: a,b,c.....y,z,aa,ab,ac,ad...zz,aaa,aab.....
This sample code implements your example in a concise manner.
The function
alpha_string_to_numbertakes astd::stringof lower case alpha and converts it into a number using the assignmentsa=1,b=2, etc. This is not base-26, but similar. The functionnumber_to_alpha_stringdoes the inverse.As far as I can tell, this is a valid lexicographical ordering in that
ais 1,bis 2,aais 27,abis 28 etc.For
zyou get 26 and foradyou get 30, the average of which is 28 orab. Now, in what sense this is the "middle" betweenzandadis up for debate, but it matches your example.You should be able to use the following to help debug your function.
Sample Code
Extended Explanation
alpha_string_to_numberkeeps track of the result innand value of the current digit inplace_digit. For base-10, place digit would cycle through the powers of ten, so 1, 10, 100, 1000, etc. For this example we have 26 characters so place digit is 1, 26, 26^2, 26^3, etc. This allows us to shift the previousnover a single place digit each time through loop as we add in the value of the current character.Note that the character values range from 1 to 26 (instead of 0 to 25) in order to make the lexicographical ordering work correctly. Hence, the +1 when converting to a number and the -1 when converting from a number.
number_to_alpha_stringkeeps track of the result stringrwhich is computed in reverse order since it is easier to extract the least significant remaining digit each time through the loop rather than the most significant. Before returning, we reverse the characters to put them in the correct order.