Traverse the alphabet from a to z using C#
P粉982881583
P粉982881583 2023-08-23 09:51:55
0
2
332
<p>I have a question about traversing the alphabet. I want a loop that starts at "a" and ends at "z". Then, the loop starts from "aa" and counts up to "az". Then start from "ba", go to "bz", and so on...</p> <p>Does anyone know a solution? </p> <h2>Thank you</h2> <p>Edit: I forgot, I give a character "a" to the function and then the function must return "b". If "bnc" is given, the function must return "bnd". </p>
P粉982881583
P粉982881583

reply all(2)
P粉764836448

First try, just use a-z then aa-zz

public static IEnumerable GetExcelColumns()
{
    for (char c = 'a'; c <= 'z'; c++)
    {
        yield return c.ToString();
    }
    char[] chars = new char[2];
    for (char high = 'a'; high <= 'z'; high++)
    {
        chars[0] = high;
        for (char low = 'a'; low <= 'z'; low++)
        {
            chars[1] = low;
            yield return new string(chars);
        }
    }
}

Note that this will stop at 'zz'. Of course, there are some ugly repetitions in the loop. Fortunately, this is easy to fix - and it can also be more flexible:

Second attempt: a more flexible alphabet

private const string Alphabet = "abcdefghijklmnopqrstuvwxyz";

public static IEnumerable GetExcelColumns()
{
    return GetExcelColumns(Alphabet);
}

public static IEnumerable GetExcelColumns(string alphabet)
{
    foreach(char c in alphabet)
    {
        yield return c.ToString();
    }
    char[] chars = new char[2];
    foreach(char high in alphabet)
    {
        chars[0] = high;
        foreach(char low in alphabet)
        {
            chars[1] = low;
            yield return new string(chars);
        }
    }
}

Now, if you only want to generate a, b, c, d, aa, ab, ac, ad, ba, etc., you can call GetExcelColumns("abcd").

Third Attempt (Further Revised) - Infinite Sequence

public static IEnumerable GetExcelColumns(string alphabet)
{
    int length = 0;
    char[] chars = null;
    int[] indexes = null;
    while (true)
    {
        int position = length-1;
        // 尝试递增最低有效值。
        while (position >= 0)
        {
            indexes[position]++;
            if (indexes[position] == alphabet.Length)
            {
                for (int i=position; i < length; i++)
                {
                    indexes[i] = 0;
                    chars[i] = alphabet[0];
                }
                position--;
            }
            else
            {
                chars[position] = alphabet[indexes[position]];
                break;
            }
        }
        // 如果我们到达数组的开始位置,我们需要一个额外的值
        if (position == -1)
        {
            length++; 
            chars = new char[length];
            indexes = new int[length];
            for (int i=0; i < length; i++)
            {
                chars[i] = alphabet[0];
            }
        }
        yield return new string(chars);
    }
}

Maybe using recursion will lead to clearer code, but the efficiency will not be that high.

Please note that if you want to stop at a specific point, you can use LINQ:

var query = GetExcelColumns().TakeWhile(x => x != "zzz");

"Restart" iterator

To restart the iterator from a given point, you can use SkipWhile as thesoftwarejedi suggested. Of course, this is quite inefficient. If you can maintain any state between calls, you can retain the iterator (for either solution):

using (IEnumerator iterator = GetExcelColumns())
{
    iterator.MoveNext();
    string firstAttempt = iterator.Current;

    if (someCondition)
    {
        iterator.MoveNext();
        string secondAttempt = iterator.Current;
        // etc
    }
}

Alternatively, you might be able to structure your code to use foreach, breaking when the first value is found that can actually be used.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!