反复阅读字母表-C#a-caz

反复阅读字母表-C#a-caz,c#,count,loops,iteration,alphabet,C#,Count,Loops,Iteration,Alphabet,我有一个关于反复阅读字母表的问题。 我希望有一个以“a”开头,以“z”结尾的循环。之后,循环开始“aa”,并计数到“az”。然后从“ba”到“bz”等等 有人知道一些解决办法吗 谢谢 编辑:我忘了给函数一个字符“a”,然后函数必须返回b。如果你给出“bnc”,那么函数必须返回“bnd”这就像显示一个int,只使用基数26而不是基数10。尝试以下算法查找数组的第n个条目 q = n div 26; r = n mod 26; s = ''; while (q > 0 || r > 0)

我有一个关于反复阅读字母表的问题。 我希望有一个以“a”开头,以“z”结尾的循环。之后,循环开始“aa”,并计数到“az”。然后从“ba”到“bz”等等

有人知道一些解决办法吗

谢谢
编辑:我忘了给函数一个字符“a”,然后函数必须返回b。如果你给出“bnc”,那么函数必须返回“bnd”

这就像显示一个int,只使用基数26而不是基数10。尝试以下算法查找数组的第n个条目

q = n div 26;
r = n mod 26;
s = '';
while (q > 0 || r > 0) {
  s = alphabet[r] + s;
  q = q div 26;
  r = q mod 26;
}

当然,如果您想要前n个条目,这不是最有效的解决方案。在本例中,请尝试类似daniel的解决方案。

以下内容将用所需字符串填充列表:

List<string> result = new List<string>();
for (char ch = 'a'; ch <= 'z'; ch++){
    result.Add (ch.ToString());
}

for (char i = 'a'; i <= 'z'; i++)
{
    for (char j = 'a'; j <= 'z'; j++)
    {
        result.Add (i.ToString() + j.ToString());
    }
}
列表结果=新列表();

对于(char ch='a';ch第一次努力,先是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);
        }
    }
}
使用递归的代码可能会更干净,但效率不会那么高

请注意,如果要在某一点停止,可以使用LINQ:

var query = GetExcelColumns().TakeWhile(x => x != "zzz");
重新启动迭代器

要从给定点重新启动迭代器,您确实可以按照SoftwareEdi的建议使用
SkipWhile
。当然,这是相当低效的。如果您能够在调用之间保持任何状态,您可以只保留迭代器(对于任一解决方案):

使用(IEnumerator迭代器=GetExcelColumns())
{
iterator.MoveNext();
string firsttrunt=iterator.Current;
如果(某些条件)
{
iterator.MoveNext();
字符串secondtrument=iterator.Current;
//等
}
}

或者,您也可以构建代码以使用foreach
,只需在实际使用的第一个值上进行突破。

下面是我使用递归的尝试:

public static void PrintAlphabet(string alphabet, string prefix)
{
    for (int i = 0; i < alphabet.Length; i++) {
        Console.WriteLine(prefix + alphabet[i].ToString());
    }

    if (prefix.Length < alphabet.Length - 1) {
        for (int i = 0; i < alphabet.Length; i++) {
            PrintAlphabet(alphabet, prefix + alphabet[i]);
        }
    }
}
公共静态无效打印字母表(字符串字母表,字符串前缀)
{
for(int i=0;i
然后只需调用
PrintAlphabet(“abcd”和“)

编辑:使其完全按照OP的最新编辑要求执行

这是最简单的解决方案,经过测试:

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;
}
static void Main(字符串[]args)
{
控制台写入线(GetNextBase26(“a”);
控制台写入线(GetNextBase26(“bnc”);
}
私有静态字符串GetNextBase26(字符串a)
{
返回Base26Sequence().SkipWhile(x=>x!=a).Skip(1.First();
}
私有静态IEnumerable Base26Sequence()
{
长i=0L;
while(true)
产生返回Base26Encode(i++);
}
私有静态字符[]base26Chars=“abcdefghijklmnopqrstuvxyz”.tocharray();
专用静态字符串Base26Encode(Int64值)
{
字符串returnValue=null;
做
{
returnValue=base26Chars[value%26]+returnValue;
数值/=26;
}while(值--!=0);
返回值;
}

我尝试了一下,想出了这个:

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

namespace Alphabetty
{
    class Program
    {
        const string alphabet = "abcdefghijklmnopqrstuvwxyz";
        static int cursor = 0;
        static int prefixCursor;
        static string prefix = string.Empty;
        static bool done = false;
        static void Main(string[] args)
        {
            string s = string.Empty;
            while (s != "Done")
            {
                s = GetNextString();
                Console.WriteLine(s);
            }
            Console.ReadKey();

        }        
        static string GetNextString()
        {
            if (done) return "Done";
            char? nextLetter = GetNextLetter(ref cursor);
            if (nextLetter == null)
            {
                char? nextPrefixLetter = GetNextLetter(ref prefixCursor);
                if(nextPrefixLetter == null)
                {
                    done = true;
                    return "Done";
                }
                prefix = nextPrefixLetter.Value.ToString();
                nextLetter = GetNextLetter(ref cursor);
            }

            return prefix + nextLetter;
        }

        static char? GetNextLetter(ref int letterCursor)
        {
            if (letterCursor == alphabet.Length)
            {
                letterCursor = 0;
                return null;
            }

            char c = alphabet[letterCursor];
            letterCursor++;
            return c;
        }
    }
}

我知道这里有很多答案,其中一个已经被接受,但在我看来,这些答案都让事情变得更加困难。我认为下面的答案更简单、更清晰:

static string NextColumn(string column){
    char[] c = column.ToCharArray();
    for(int i = c.Length - 1; i >= 0; i--){
        if(char.ToUpper(c[i]++) < 'Z')
            break;
        c[i] -= (char)26;
        if(i == 0)
            return "A" + new string(c);
    }
    return new string(c);
}
这两个函数是基于零的。也就是说,“A”=0,“Z”=25,“AA”=26等等。要使它们基于一个函数(如Excel的COM接口),请删除每个函数中注释行上方的行,并取消注释这些行


NextColumn
函数一样,这些函数不会验证它们的输入。如果它们得到的是垃圾,它们都会给你带来垃圾。

只是好奇,为什么不呢

    private string alphRecursive(int c) {
         var alphabet = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
         if (c >= alphabet.Length) {
             return alphRecursive(c/alphabet.Length) + alphabet[c%alphabet.Length];
         } else {
             return "" + alphabet[c%alphabet.Length];
         }
    }

这是我想到的

/// <summary>
/// Return an incremented alphabtical string
/// </summary>
/// <param name="letter">The string to be incremented</param>
/// <returns>the incremented string</returns>
public static string NextLetter(string letter)
{
  const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  if (!string.IsNullOrEmpty(letter))
  {
    char lastLetterInString = letter[letter.Length - 1];

    // if the last letter in the string is the last letter of the alphabet
    if (alphabet.IndexOf(lastLetterInString) == alphabet.Length - 1) 
    {
        //replace the last letter in the string with the first leter of the alphbat and get the next letter for the rest of the string
        return NextLetter(letter.Substring(0, letter.Length - 1)) + alphabet[0];
    }
    else 
    {
      // replace the last letter in the string with the proceeding letter of the alphabet
      return letter.Remove(letter.Length-1).Insert(letter.Length-1, (alphabet[alphabet.IndexOf(letter[letter.Length-1])+1]).ToString() );
    }
  }
  //return the first letter of the alphabet
  return alphabet[0].ToString();
}
//
///返回递增的字母字符串
/// 
///要递增的字符串
///递增的字符串
公共静态字符串NextLetter(字符串字母)
{
常量字符串字母表=“ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
如果(!string.IsNullOrEmpty(字母))
{
char lastLetterInString=字母[letter.Length-1];
//如果字符串中的最后一个字母是字母表中的最后一个字母
if(字母索引of(lastLetterInString)=字母长度-1)
{
//用alphbat的第一个leter替换字符串中的最后一个字母,并获取字符串其余部分的下一个字母
返回NextLetter(字母.子字符串(0,字母.长度-1))+字母表[0];
}
其他的
{
//用字母表中的前一个字母替换字符串中的最后一个字母
返回字母.Remove(字母.Length-1).Insert(字母.Length-1,(字母[alphabet.IndexOf(字母[letter.Length-1])+1])ToString());
}
}
//返回字母表的第一个字母
返回字母表[0]。ToString();
}

以下是我精心设计的一些可能类似的东西。我在试验迭代计数,以便设计一个尽可能小的编号模式,同时给我足够的唯一性

我知道,每增加一个字母字符,可能会增加26倍,但我不确定要使用多少字母、数字或图案

这就引出了下面的代码。基本上,你给它传递一个字母数字字符串,每个有字母的位置,最终都会增加到“z\z”,每个有数字的位置,最终都会增加到“9”

所以你可以称之为两种方式中的一种

//This would give you the next Itteration... (H3reIsaStup4dExamplf)
string myNextValue = IncrementAlphaNumericValue("H3reIsaStup4dExample") 

//Or Loop it resulting eventually as "Z9zzZzzZzzz9zZzzzzzz"
string myNextValue = "H3reIsaStup4dExample"
while (myNextValue != null)
{
   myNextValue = IncrementAlphaNumericValue(myNextValue)
   //And of course do something with this like write it out
}
(对我来说,我在做类似“1AA000”的事情)

公共字符串增量AlphaNumericValue(字符串值)
{
//我们只允许使用字符a-b、a-Z、0-9
if(System.Text.RegularExpressions.Regex.IsMatch(值“^[a-zA-Z0-9]+$”)==false)
{
抛出新异常(“无效字符:必须是a-Z或0-9”);
}
//我们处理每个字符,因此最好将字符串转换为字符数组进行递增
char[]myCharacterArray=Value.toCharray(
static string GetColumnName(int index){
    StringBuilder txt = new StringBuilder();
    txt.Append((char)('A' + index % 26));
    //txt.Append((char)('A' + --index % 26));
    while((index /= 26) > 0)
        txt.Insert(0, (char)('A' + --index % 26));
    return txt.ToString();
}
static int GetColumnIndex(string name){
    int rtn = 0;
    foreach(char c in name)
        rtn = rtn * 26 + (char.ToUpper(c) - '@');
    return rtn - 1;
    //return rtn;
}
    private string alphRecursive(int c) {
         var alphabet = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
         if (c >= alphabet.Length) {
             return alphRecursive(c/alphabet.Length) + alphabet[c%alphabet.Length];
         } else {
             return "" + alphabet[c%alphabet.Length];
         }
    }
/// <summary>
/// Return an incremented alphabtical string
/// </summary>
/// <param name="letter">The string to be incremented</param>
/// <returns>the incremented string</returns>
public static string NextLetter(string letter)
{
  const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  if (!string.IsNullOrEmpty(letter))
  {
    char lastLetterInString = letter[letter.Length - 1];

    // if the last letter in the string is the last letter of the alphabet
    if (alphabet.IndexOf(lastLetterInString) == alphabet.Length - 1) 
    {
        //replace the last letter in the string with the first leter of the alphbat and get the next letter for the rest of the string
        return NextLetter(letter.Substring(0, letter.Length - 1)) + alphabet[0];
    }
    else 
    {
      // replace the last letter in the string with the proceeding letter of the alphabet
      return letter.Remove(letter.Length-1).Insert(letter.Length-1, (alphabet[alphabet.IndexOf(letter[letter.Length-1])+1]).ToString() );
    }
  }
  //return the first letter of the alphabet
  return alphabet[0].ToString();
}
//This would give you the next Itteration... (H3reIsaStup4dExamplf)
string myNextValue = IncrementAlphaNumericValue("H3reIsaStup4dExample") 

//Or Loop it resulting eventually as "Z9zzZzzZzzz9zZzzzzzz"
string myNextValue = "H3reIsaStup4dExample"
while (myNextValue != null)
{
   myNextValue = IncrementAlphaNumericValue(myNextValue)
   //And of course do something with this like write it out
}
public string IncrementAlphaNumericValue(string Value)
    {
        //We only allow Characters a-b, A-Z, 0-9
        if (System.Text.RegularExpressions.Regex.IsMatch(Value, "^[a-zA-Z0-9]+$") == false)
        {
            throw new Exception("Invalid Character: Must be a-Z or 0-9");
        }

        //We work with each Character so it's best to convert the string to a char array for incrementing
        char[] myCharacterArray = Value.ToCharArray();

        //So what we do here is step backwards through the Characters and increment the first one we can. 
        for (Int32 myCharIndex = myCharacterArray.Length - 1; myCharIndex >= 0; myCharIndex--)
        {
            //Converts the Character to it's ASCII value
            Int32 myCharValue = Convert.ToInt32(myCharacterArray[myCharIndex]);

            //We only Increment this Character Position, if it is not already at it's Max value (Z = 90, z = 122, 57 = 9)
            if (myCharValue != 57 && myCharValue != 90 && myCharValue != 122)
            {
                myCharacterArray[myCharIndex]++;

                //Now that we have Incremented the Character, we "reset" all the values to the right of it
                for (Int32 myResetIndex = myCharIndex + 1; myResetIndex < myCharacterArray.Length; myResetIndex++)
                {
                    myCharValue = Convert.ToInt32(myCharacterArray[myResetIndex]);
                    if (myCharValue >= 65 && myCharValue <= 90)
                    {
                        myCharacterArray[myResetIndex] = 'A';
                    }
                    else if (myCharValue >= 97 && myCharValue <= 122)
                    {
                        myCharacterArray[myResetIndex] = 'a';
                    }
                    else if (myCharValue >= 48 && myCharValue <= 57)
                    {
                        myCharacterArray[myResetIndex] = '0';
                    }
                }

                //Now we just return an new Value
                return new string(myCharacterArray);
            } 
        }

        //If we got through the Character Loop and were not able to increment anything, we retun a NULL. 
        return null;  
    }