4
\$\begingroup\$

I'm creating a C# application that produces unique lines of data. The main purpose of the application is for me to learn C#. The secondary purpose is to have available lines of (dummy) data when testing database development.

For this particular question I'm concerned with the most efficient algorithm for incrementing characters by one. The function that I have at present receives a default value of "A". This value is incremented by one until "Z" is checked. When iteration increments to letter "Z" it converts this value back to "A" and a new letter "A" is added to the end of the sequence.

Example output:

A  
B  
C  
...  
Z  
AA  
AB  
AC  
...  
AZ  
BA  
BB  
BC

The string going in as parameter is split by adding each char into a List. A switch evaluates how many elements there are in the List executing the appropriate case block for incrementation. Each case checks if the value of the present array element is the letter "Z". If true the "Z" is converted to "A" and the previous char is incremented by one. If all previous values are "Z", all elements are converted to "A" and a new char "A" is added to the List. Finally all elements in the List are united into a single object with StringBuilder for final string return.

I have the function working with basic logic using if/else statements but this is not the best solution. The end result is not the problem because I'm getting the right result in the desired order. What I'm interested is learning alternatives to the if/else statement approach. I would like to make it more efficient using short iteration statements limiting code-block nesting.

using System;
using System.Collections.Generic;
using System.Text;

namespace FileReadWrite
{
    public class RegexHandlerUtils
    {
        public string AddPrefixToSequence(string prefixStr)
        {
            char validateZ = 'Z';
            List<char> prefixSequence = new List<char>();

            foreach (var item in prefixStr)
            {
                prefixSequence.Add(item);
            }

            int amountOfElements = prefixSequence.Count;
            switch (amountOfElements)
            {
                case 2:
                    if (prefixSequence[1].Equals(validateZ))
                    {
                        if (prefixSequence[0].Equals(validateZ))
                        {
                            prefixSequence[0] = 'A';
                            prefixSequence[1] = 'A';
                            prefixSequence.Add('A');
                        }
                        else
                        {
                            prefixSequence[0]++;
                            prefixSequence[1] = 'A';
                        }
                    }
                    else
                    {
                        prefixSequence[1]++;
                    }
                    break;
                case 3:
                    if (prefixSequence[2].Equals(validateZ))
                    {
                        if (prefixSequence[1].Equals(validateZ))
                        {
                            if (prefixSequence[0].Equals(validateZ))
                            {
                                prefixSequence[0] = 'A';
                                prefixSequence[1] = 'A';
                                prefixSequence[2] = 'A';
                                prefixSequence.Add('A');

                            }
                            else
                            {
                                prefixSequence[0]++;
                                prefixSequence[1] = 'A';
                                prefixSequence[2] = 'A';
                            }
                        }
                        else
                        {
                            prefixSequence[1]++;
                            prefixSequence[2] = 'A';
                        }
                    }
                    else
                    {
                        prefixSequence[2]++;
                    }
                    break;
                default:
                    if (prefixSequence[0].Equals(validateZ))
                    {
                        prefixSequence[0] = 'A';
                        prefixSequence.Add('A');
                    }
                    else
                    {
                        prefixSequence[0]++;
                    }
                    break;
            }

            StringBuilder strBuild = new StringBuilder();
            foreach (var item in prefixSequence)
            {
                strBuild.Append(item);
            }

            return strBuild.ToString();
        }
    }
}
\$\endgroup\$
3
\$\begingroup\$

You're manually handling the cases ZAA, ZZAAA, and ZZZAAAA, but your code doesn't scale beyond that. (In fact, it behaves weirdly when overflow happens.) You're using a List<char>, where it would have been simpler just to work on a StringBuilder directly.

This kind of task has been solved before. I happen to like this solution. You could do ToName(1 + ToNumber(str)) for much less code than what you wrote, and you would also have two useful number-system conversion functions as well.

\$\endgroup\$
  • \$\begingroup\$ Thanks for linking other questions with same objective they give the alternate design approach that I was hoping for. I see that focusing in the math logic behind the problem is more important than program language specifics. \$\endgroup\$ – Alejandro Dec 1 '16 at 14:21
1
\$\begingroup\$

I think maybe you're overthinking this. A string constructor can take the character and a count of how many times to repeat it. A simple for loop and some math to decide which character and how many will fill the array:

static string[] MakeArray(int size)
{
    string[] outVal = new string[size];
    for (int i = 0; i < size; i++)
    {
        outVal[i] = new string((char)('A' + (i % 26)), (i / 26) + 1);
    }
    return outVal;
}

This will scale to whichever size you want.

\$\endgroup\$
  • \$\begingroup\$ I agree. I think I focused to much on programming language functionality. \$\endgroup\$ – Alejandro Dec 1 '16 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.