猿问

C#创建带有数字和字符的字符串序列

我正在尝试创建格式的数字序列,一旦到达我想使用前导字母继续序列。string"99999"

例子:

"00000" -> "00100" -> "99999" -> "A0001" -> "A9999" -> "B0001" -> "ZZZZZ"

有没有简单的方法来实现这一点?

到目前为止,我尝试string的数字和字母分开,然后如果数字达到最大值,我会检查一些代码,如果它达到可用的最大值,我会添加一个字母。对我来说看起来并不优雅。


繁星coding
浏览 161回答 2
2回答

子衿沉夜

让我们实现GetNextValue方法:对于给定 value的(例如"A9999"),我们计算下一个("B0001"):private static string GetNextValue(string value) {&nbsp; StringBuilder sb = new StringBuilder(value);&nbsp; // Digits only: 1239 -> 1240&nbsp; for (int i = value.Length - 1; i >= 0; --i) {&nbsp; &nbsp; if (sb[i] < '9') {&nbsp; &nbsp; &nbsp; sb[i] = (char)(sb[i] + 1);&nbsp; &nbsp; &nbsp; return sb.ToString();&nbsp; &nbsp; }&nbsp; &nbsp; else if (sb[i] >= 'A')&nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; sb[i] = '0';&nbsp; }&nbsp; // 1st letter: 9999 -> A001&nbsp; if (sb[0] == '0') {&nbsp; &nbsp; sb[0] = 'A';&nbsp; &nbsp; if (sb[sb.Length - 1] == '0')&nbsp; &nbsp; &nbsp; sb[sb.Length - 1] = '1';&nbsp; &nbsp; return sb.ToString();&nbsp; }&nbsp; // Leading letters AZ999 -> BA001&nbsp; for (int i = value.Length - 1; i >= 0; --i) {&nbsp; &nbsp; if (sb[i] >= 'A') {&nbsp; &nbsp; &nbsp; if (sb[i] < 'Z') {&nbsp; &nbsp; &nbsp; &nbsp; sb[i] = (char)(sb[i] + 1);&nbsp; &nbsp; &nbsp; &nbsp; if (sb[sb.Length - 1] == '0')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sb[sb.Length - 1] = '1';&nbsp; &nbsp; &nbsp; &nbsp; return sb.ToString();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; sb[i] = 'A';&nbsp; &nbsp; }&nbsp; }&nbsp; // All letters increment: ABCDZ -> ABCEA&nbsp; for (int i = 0; i < value.Length; ++i) {&nbsp; &nbsp; if (sb[i] == '0') {&nbsp; &nbsp; &nbsp; sb[i] = 'A';&nbsp; &nbsp; &nbsp; if (sb[sb.Length - 1] == '0')&nbsp; &nbsp; &nbsp; &nbsp; sb[sb.Length - 1] = '1';&nbsp; &nbsp; &nbsp; return sb.ToString();&nbsp; &nbsp; }&nbsp; }&nbsp; // Exhausting: ZZZZZ -> 00000&nbsp; return new string('0', value.Length);}如果要枚举这些值:private static IEnumerable<string> Generator(int length = 5) {&nbsp; string item = new string('0', length);&nbsp; do {&nbsp; &nbsp; yield return item;&nbsp; &nbsp; item = GetNextValue(item);&nbsp; }&nbsp; while (!item.All(c => c == '0'));}演示:(让我们使用一个长度字符串3)Console.Write(string.Join(Environment.NewLine, Generator(3)));结果:(项目27234总数;18769482项目如果length == 5)000001002...009010...999A01...A99B01...Z99AA1...AA9AB1...AZ9BA1...ZZ9AAAAABAAC...AAZABA...ZZYZZZ

慕莱坞森

这是一个扩展方法,它将整数值格式化为您的格式(带前导字母):public static string ToZormat(this int value, int length = 5){&nbsp; &nbsp; string map = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";&nbsp; &nbsp; char[] result = new char[length];&nbsp; &nbsp; var x = value;&nbsp; &nbsp; for(int i = 0; i < length; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; int threshold = (int)Math.Pow(10, length - i - 1);&nbsp; &nbsp; &nbsp; &nbsp; var index = Math.Min(map.Length - 1, x / threshold);&nbsp; &nbsp; &nbsp; &nbsp; result[i] = map[index];&nbsp; &nbsp; &nbsp; &nbsp; x -= threshold * index;&nbsp; &nbsp; }&nbsp; &nbsp; return new String(result);}当您将数字格式化为长度为 5 的字符串时,前导字母会出现在 value 99,999、 next go A0,000、 ...A9,999等之后B0,000。如您所见,第一个字符会更改每个10,000数字。第二个字符改变每个1,000数字。最后,每个数字的第五个字符都会改变。我们只需要实现那个算法。基本步骤:定义格式中使用的字符映射计算当前位置 (i) 的字符变化阈值 - 它将是 10 的幂:10,000, 1,000, 100, 10, 1。从地图中获取字符索引。它只是适合该值的阈值数,但不超过地图中的字符数。计算输入值的剩余部分并转到下一个位置您应该为适合格式化字符串的给定长度的最大值添加验证。长度 3 的样本:Enumerable.Range(0, 3886).Select(x => x.ToZormat(3))输出:000001002...999A00A01...A99B00B01...Z99ZA0ZA1...ZZ9ZZA...ZZZ
随时随地看视频慕课网APP
我要回答