Minimising string length
If you want to keep the string lengths to a minimum, you could create a string that is lexicographically halfway between the left and right strings, so that there is room to insert additional strings, and only create a longer string if absolutely necessary.
I will assume an alphabet [a-z], and a lexicographical ordering where an empty space comes before 'a', so that e.g. "ab" comes before "abc".
Basic case
You start by copying the characters from the beginning of the strings, until you encounter the first difference, which could be either two different characters, or the end of the left string:
abcde ~ abchi -> abc + d ~ h
abc ~ abchi -> abc + _ ~ h
The new string is then created by appending the character that is halfway in the alphabet between the left character (or the beginning of the alphabet) and the right character:
abcde ~ abchi -> abc + d ~ h -> abcf
abc ~ abchi -> abc + _ ~ h -> abcd
Consecutive characters
If the two different characters are lexicographically consecutive, first copy the left character, and then append the character halfway between the next character from the left string and the end of the alphabet:
abhs ~ abit -> ab + h ~ i -> abh + s ~ _ -> abhw
abh ~ abit -> ab + h ~ i -> abh + _ ~ _ -> abhn
If the next character(s) in the left string are one or more z's, then copy them and append the character halfway between the first non-z character and the end of the alphabet:
abhz ~ abit -> ab + h ~ i -> abh + z ~ _ -> abhz + _ ~ _ -> abhzn
abhzs ~ abit -> ab + h ~ i -> abh + z ~ _ -> abhz + s ~ _ -> abhzw
abhzz ~ abit -> ab + h ~ i -> abh + z ~ _ -> ... -> abhzz + _ ~ _ -> abhzzn
Right character is a or b
You should never create a string by appending an 'a' to the left string, because that would create two lexicographically consecutive strings, inbetween which no further strings could be added. The solution is to always append an additional character, halfway inbetween the beginning of the alphabet and the next character from the right string:
abc ~ abcah -> abc + _ ~ a -> abca + _ ~ h -> abcad
abc ~ abcab -> abc + _ ~ a -> abca + _ ~ b -> abcaa + _ ~ _ -> abcaan
abc ~ abcaah -> abc + _ ~ a -> abca + _ ~ a -> abcaa + _ ~ h -> abcaad
abc ~ abcb -> abc + _ ~ b -> abca + _ ~ _ -> abcan
Code examples
Below is a code snippet which demonstrates the method. It's a bit fiddly because JavaScript, but not actually complicated. To generate a first string, call the function with two empty strings; this will generate the string "n". To insert a string before the leftmost or after the rightmost string, call the function with that string and an empty string.
function midString(prev, next) {
var p, n, pos, str;
for (pos = 0; p == n; pos++) { // find leftmost non-matching character
p = pos < prev.length ? prev.charCodeAt(pos) : 96;
n = pos < next.length ? next.charCodeAt(pos) : 123;
}
str = prev.slice(0, pos - 1); // copy identical part of string
if (p == 96) { // prev string equals beginning of next
while (n == 97) { // next character is 'a'
n = pos < next.length ? next.charCodeAt(pos++) : 123; // get char from next
str += 'a'; // insert an 'a' to match the 'a'
}
if (n == 98) { // next character is 'b'
str += 'a'; // insert an 'a' to match the 'b'
n = 123; // set to end of alphabet
}
}
else if (p + 1 == n) { // found consecutive characters
str += String.fromCharCode(p); // insert character from prev
n = 123; // set to end of alphabet
while ((p = pos < prev.length ? prev.charCodeAt(pos++) : 96) == 122) { // p='z'
str += 'z'; // insert 'z' to match 'z'
}
}
return str + String.fromCharCode(Math.ceil((p + n) / 2)); // append middle character
}
var strings = ["", ""];
while (strings.length < 100) {
var rnd = Math.floor(Math.random() * (strings.length - 1));
strings.splice(rnd + 1, 0, midString(strings[rnd], strings[rnd + 1]));
document.write(strings + "<br>");
}