Rumah > Soal Jawab > teks badan
P粉7648364482023-08-24 00:42:38
Percubaan pertama, cuma guna a-z kemudian 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); } } }
Perhatikan bahawa ini akan berhenti di 'zz'. Sudah tentu, terdapat beberapa pengulangan hodoh dalam gelung. Nasib baik, ini mudah untuk diperbaiki - dan ia boleh menjadi lebih fleksibel:
Cubaan kedua: abjad yang lebih fleksibel
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); } } }
Kini, jika anda hanya ingin menjana a, b, c, d, aa, ab, ac, ad, ba, dan lain-lain, anda boleh menghubungi GetExcelColumns("abcd")
.
Percubaan Ketiga (Disemak Lanjut) - Urutan Tak Terhingga
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); } }
Mungkin menggunakan rekursi akan menghasilkan kod yang lebih bersih, tetapi ia tidak secekap itu.
Sila ambil perhatian bahawa jika anda ingin berhenti pada titik tertentu anda boleh menggunakan LINQ:
var query = GetExcelColumns().TakeWhile(x => x != "zzz");
"mulakan semula" lelaran
Untuk memulakan semula iterator dari titik tertentu, anda boleh menggunakan SkipWhile
seperti yang dicadangkan oleh perisian tersebut. Sudah tentu, ini agak tidak cekap. Jika anda boleh mengekalkan sebarang keadaan di antara panggilan, anda boleh mengekalkan lelaran (untuk mana-mana penyelesaian):
using (IEnumerator<string> iterator = GetExcelColumns()) { iterator.MoveNext(); string firstAttempt = iterator.Current; if (someCondition) { iterator.MoveNext(); string secondAttempt = iterator.Current; // etc } }
Sebagai alternatif, anda mungkin boleh menstruktur kod anda untuk digunakan foreach
, pecah apabila nilai pertama ditemui yang sebenarnya boleh digunakan.
P粉9204852852023-08-24 00:23:16
EDIT: Jadikan ia betul-betul mengikut suntingan terkini siaran asal
Ini adalah penyelesaian paling mudah dan diuji:
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; }