Parcourez l'alphabet de a à z en utilisant C#
P粉982881583
P粉982881583 2023-08-23 09:51:55
0
2
498
<p>J'ai une question sur la traversée de l'alphabet. Je veux une boucle qui commence à "a" et se termine à "z". Ensuite, la boucle commence à partir de « aa » et compte jusqu'à « az ». Commencez ensuite par "ba", allez à "bz", et ainsi de suite...</p> <p> Quelqu'un connaît-il une solution ? </p> <h2>Merci</h2> <p>Edit : J'ai oublié, je donne un caractère "a" à la fonction et ensuite la fonction doit retourner "b". Si "bnc" est donné, la fonction doit renvoyer "bnd". </p>
P粉982881583
P粉982881583

répondre à tous(2)
P粉764836448

Essayez d'abord, utilisez simplement a-z puis 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);
        }
    }
}

Notez que cela s'arrêtera à « zz ». Bien sûr, il y a quelques vilaines répétitions dans la boucle. Heureusement, c'est facile à résoudre - et cela peut être encore plus flexible :

Deuxième essai : un alphabet plus flexible

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);
        }
    }
}

Maintenant, si vous souhaitez simplement générer a, b, c, d, aa, ab, ac, ad, ba, etc., vous pouvez appeler GetExcelColumns("abcd").

Troisième tentative (révisée davantage) - Séquence infinie

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);
    }
}

Peut-être que l'utilisation de la récursion entraînera un code plus propre, mais ce ne sera pas aussi efficace.

Veuillez noter que si vous souhaitez vous arrêter à un point précis, vous pouvez utiliser LINQ :

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

Itérateur "redémarrer"

Pour redémarrer l'itérateur à partir d'un point donné, vous pouvez utiliser SkipWhile comme suggéré par le logicieljedi. Bien entendu, cela est assez inefficace. Si vous pouvez conserver n'importe quel état entre les appels, vous pouvez conserver l'itérateur (pour l'une ou l'autre solution) :

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

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

Alternativement, vous pourrez peut-être structurer votre code pour l'utiliser foreach, en le cassant lorsque la première valeur pouvant réellement être utilisée est trouvée.

P粉920485285

EDIT : faites-le exactement selon la dernière modification du message original

C'est la solution la plus simple et testée :

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;
}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal