Home > Back-end >  Write a function to generate all strings between two given strings
Write a function to generate all strings between two given strings

Time:12-20

Write a function to generate all strings between two given strings, for example if first string is “ABC01” and second is “ADE05” following list should be the result of the code. Incrementing the integers and alphabets in chronological order.

Assuming Alphabet or integer in second string is always greater than first string. If there is an integer at 4th and 5th index in first string then in second string 4th and 5th index is an integer. "BBBBB" and "BBB05" is invalid

Input: "ABC01" "ADE05"

Output sequence:

ABC01,ABC02,ABC03,ABC04,ABC05, ABD01,ABD02,ABD03,ABD04,ABD05, ABE01,ABE02,ABE03,ABE04,ABE05, ACC01,ACC02,ACC03,ACC04,ACC05, ACD01,ACD02,ACD03,ACD04,ACD05, ACE01,ACE02,ACE03,ACE04,ACE05, ADC01,ADC02,ADC03,ADC04,ADC05, ADD01,ADD02,ADD03,ADD04,ADD05, ADE01,ADE02,ADE03,ADE04,ADE05

I have tried following but it only update last digit. Can anyone suggest implementation for generating this sequence in any language. Thanks in advance

public class PrintStringSequence
{
    static void PrintSequence(String string1, String string2)
    {
        if (string1.Length != string2.Length)
        {
            Console.WriteLine("String length should be equal");
            return;
        }

        char[] start = string1.ToCharArray();
        char[] end = string2.ToCharArray();
        String res = "";
        
            for (char letter0 = start[0]; letter0 <= end[0]; letter0  )
            {
                for (char letter1 = start[1]; letter1 <= end[1]; letter1  )
                {
                    for (char letter2 = start[2]; letter2 <= end[2]; letter2  )
                    {
                         for (char letter3 = start[3]; letter3 <= end[3]; letter3  )
                         {   
                             for (char letter4 = start[4]; letter4 <= end[4]; letter4  )
                             {
                                 res = string1.Remove(4).Insert(4, letter4.ToString());
                                 Console.WriteLine(res);
                             }
                             res = string1.Remove(3).Insert(3, letter3.ToString());
                         }
                         res = string1.Remove(2).Insert(2, letter2.ToString());
                    }
                    res = string1.Remove(1).Insert(1, letter1.ToString());
                }
                res = string1.Remove(0).Insert(0, letter0.ToString());
            }     
    }

    public static void Main()
    {
        PrintSequence("ABC01", "ADE05");
    }
}

I am getting enter image description here

CodePudding user response:

You should iterate from right to left.

E.g. For 1 to 5, you create 5 arrays {1}, {2}, {3}, {4}, {5}.

For each of those 5 arrays, you prepend the next element, 0. It is the same, so you would have no nested loops. You now have {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}.

Then C to E, this has a nested loop. {C, 0, 1}, {D, 0, 1}, {E, 0, 1}, {C, 0, 2}, and so on. Should end up with 15 elements.

... Repeat until you reach index zero in both strings. Then convert those arrays into strings, and print. If order matters, then sort the strings afterwards rather than during this process.

Ideally, you check that your input strings have the same length before starting this process, as well as validate each index are both digits or letters, as you mention.

CodePudding user response:

your approach for nested for loops, one for each letter, may end up being potentially technically correct; however, it is extremely inflexible and not really in DRY (Don't Repeat Yourself) best practices. I would advise iterating over each index of the first string and adding to it until you get to the next string. Break the problem into pieces. First figure out how to find all the characters between two characters, and then use that to find all the strings between two strings by applying that function to each character.

Something like

public char[] FindAllCharactersBetween(char start, char end)
{
  var result = new List<char>();
  var iter = start   1;
  while(iter < end) 
  {
    result.Add(iter);
    iter  ;
  }
  return result.ToArray();
}

Use something like that to iterate over each index of start and substitute the results of that function in for each character.

CodePudding user response:

Increment the rightmost character, starting from the first value, until the second one (e.g. from 1 to 5). Then reset to the first and carry to the next character to the left. Note that in the case of the 0, the carry immediately causes an overflow of the value, causing a reset and a carry to the next (C). The enumeration stops on a carry out of the leftmost character.

ABC01 > ABC02 > ABC03 > ABC04 > ABC05 > ABC06=ABC11=ABD01 > ABD02 > ABD03 > ABD04 > ABD05 > ABD060=ABD11=ABE01 > ABE02 > ABE03 > ABE04 > ABE05 > ABE06=ABE11=ABF11=ACC01 ...

CodePudding user response:

If you do

var start = "the cat";
for (int i =0; i<5; i  )
{
    var loop = start.Remove(0);
    Console.WriteLine(loop);
}

you will get 5 times "he cat". Remove does not mutate the original string. Neither does Insert.

If you need to keep changes, you need to reassign the var:

var start = "the cat";
for (int i =0; i<5; i  )
{
    start = start.Remove(0);
    Console.WriteLine(start);
}

Will then go

he cat
e cat
 cat
cat
at

Note that this only explains why your code does what it does and how you can fix that.

The result would still be highly inefficient and inflexible.

The changes for you would be:

String res = string1;
        
for (char letter0 = start[0]; letter0 <= end[0]; letter0  )
{
    for (char letter1 = start[1]; letter1 <= end[1]; letter1  )
    {
        for (char letter2 = start[2]; letter2 <= end[2]; letter2  )
        {
             for (char letter3 = start[3]; letter3 <= end[3]; letter3  )
             {   
                 for (char letter4 = start[4]; letter4 <= end[4]; letter4  )
                 {
                     res = res.Remove(4).Insert(4, letter4.ToString());
                     Console.WriteLine(res);
                 }
                 res = res.Remove(3).Insert(3, letter3.ToString());
             }
             res = res.Remove(2).Insert(2, letter2.ToString());
        }
        res = res.Remove(1).Insert(1, letter1.ToString());
    }
    res = res.Remove(0).Insert(0, letter0.ToString());
}

I have not tested it, though.

Also: Do not use in production code! Find a better solution. This is for educational purposes at best.

  • Related