I'm trying to create a sequence of numbers in string
format, once I reach "99999"
I want to continue the sequence using leading letters.
Example:
"00000" -> "00100" -> "99999" -> "A0001" -> "A9999" -> "B0001" -> "ZZZZZ"
Is there an easy way to achieve this ?
So far I tried to split my string
in numbers and letters and then I have some code cheking if numbers reach maximum, if it reach the maximum available I add a letter. Doesn't look really elegant to me.
答案 0 :(得分:3)
让我们实现GetNextValue
方法:对于给定的 value
(例如"A9999"
),我们计算 next ({{1 }}):
"B0001"
如果要枚举这些值:
private static string GetNextValue(string value) {
StringBuilder sb = new StringBuilder(value);
// Digits only: 1239 -> 1240
for (int i = value.Length - 1; i >= 0; --i) {
if (sb[i] < '9') {
sb[i] = (char)(sb[i] + 1);
return sb.ToString();
}
else if (sb[i] >= 'A')
break;
else
sb[i] = '0';
}
// 1st letter: 9999 -> A001
if (sb[0] == '0') {
sb[0] = 'A';
if (sb[sb.Length - 1] == '0')
sb[sb.Length - 1] = '1';
return sb.ToString();
}
// Leading letters AZ999 -> BA001
for (int i = value.Length - 1; i >= 0; --i) {
if (sb[i] >= 'A') {
if (sb[i] < 'Z') {
sb[i] = (char)(sb[i] + 1);
if (sb[sb.Length - 1] == '0')
sb[sb.Length - 1] = '1';
return sb.ToString();
}
else
sb[i] = 'A';
}
}
// All letters increment: ABCDZ -> ABCEA
for (int i = 0; i < value.Length; ++i) {
if (sb[i] == '0') {
sb[i] = 'A';
if (sb[sb.Length - 1] == '0')
sb[sb.Length - 1] = '1';
return sb.ToString();
}
}
// Exhausting: ZZZZZ -> 00000
return new string('0', value.Length);
}
演示:(让我们使用长度为private static IEnumerable<string> Generator(int length = 5) {
string item = new string('0', length);
do {
yield return item;
item = GetNextValue(item);
}
while (!item.All(c => c == '0'));
}
的字符串)
3
结果 :(总共Console.Write(string.Join(Environment.NewLine, Generator(3)));
个项目;如果27234
,则18769482
个项目
length == 5
答案 1 :(得分:0)
这是一种扩展方法,可将整数值格式化为您的格式(带前导字母):
public static string ToZormat(this int value, int length = 5)
{
string map = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] result = new char[length];
var x = value;
for(int i = 0; i < length; i++)
{
int threshold = (int)Math.Pow(10, length - i - 1);
var index = Math.Min(map.Length - 1, x / threshold);
result[i] = map[index];
x -= threshold * index;
}
return new String(result);
}
当您将数字格式设置为长度为5的字符串时,在值99,999
之后出现前导字母,接下来是A0,000
,... A9,999
,B0,000
等。如您所见,第一个字符每10,000
个数字都会变化。第二个字符每1,000
个数字更改一次。最后,每个数字的第五个字符都会改变。我们只需要实现该算法即可。
基本步骤:
10,000
,1,000
,100
,10
,{{1} }。您应该添加验证值,以适合格式化字符串的给定长度。
长度为3的样本
1
输出:
Enumerable.Range(0, 3886).Select(x => x.ToZormat(3))