用C#遍歷字母表從a到z
P粉982881583
P粉982881583 2023-08-23 09:51:55
0
2
500
<p>我有一個關於遍歷字母的問題。 我想要一個循環,從"a"開始,到"z"結束。然後,循環從"aa"開始,計數到"az"。然後從"ba"開始,一直到"bz",依此類推...</p> <p>有人知道解決辦法嗎? </p> <h2>謝謝</h2> <p>編輯:我忘了,我給一個字元"a"給函數,然後函數必須回傳"b"。如果給出"bnc",函數必須返回"bnd"。 </p>
P粉982881583
P粉982881583

全部回覆(2)
P粉764836448

第一次嘗試,只使用a-z然後是aa-zz

public static IEnumerable<string> 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);
        }
    }
}

請注意,這將在'zz'處停止。當然,循環中存在一些醜陋的重複。幸運的是,這很容易解決 - 並且它還可以更加靈活:

第二次嘗試:更靈活的字母

private const string Alphabet = "abcdefghijklmnopqrstuvwxyz";

public static IEnumerable<string> GetExcelColumns()
{
    return GetExcelColumns(Alphabet);
}

public static IEnumerable<string> 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);
        }
    }
}

現在,如果你只想產生a、b、c、d、aa、ab、ac、ad、ba等,你可以呼叫GetExcelColumns("abcd")

第三次嘗試(進一步修訂)- 無限序列

#
public static IEnumerable<string> 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);
    }
}

可能使用遞迴會有更清晰的程式碼,但效率不會那麼高。

請注意,如果你想在某個特定點停止,你可以使用LINQ:

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

「重新啟動」迭代器

要從給定點重新啟動迭代器,你可以像thesoftwarejedi建議的那樣使用SkipWhile。當然,這相當低效。如果你能在呼叫之間保持任何狀態,你可以保留迭代器(對於任一解決方案):

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

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

或者,你可能能夠建立你的程式碼以使用foreach,在找到第一個可以實際使用的值時中斷。

P粉920485285

編輯:使其完全按照原始帖子的最新編輯要求執行

#

這是最簡單的解決方案,並經過測試:

static void Main(string[] args)
{
    Console.WriteLine(GetNextBase26("a"));
    Console.WriteLine(GetNextBase26("bnc"));
}

private static string GetNextBase26(string a)
{
    return Base26Sequence().SkipWhile(x => x != a).Skip(1).First();
}

private static IEnumerable<string> Base26Sequence()
{
    long i = 0L;
    while (true)
        yield return Base26Encode(i++);
}

private static char[] base26Chars = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
private static string Base26Encode(Int64 value)
{
    string returnValue = null;
    do
    {
        returnValue = base26Chars[value % 26] + returnValue;
        value /= 26;
    } while (value-- != 0);
    return returnValue;
}
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板