C# create string sequence with both number and characters

时间:2018-12-19 11:16:17

标签: c# string

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.

2 个答案:

答案 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,999B0,000等。如您所见,第一个字符每10,000个数字都会变化。第二个字符每1,000个数字更改一次。最后,每个数字的第五个字符都会改变。我们只需要实现该算法即可。

基本步骤:

  • 定义在您的格式中使用的字符图
  • 计算当前位置(i)的字符更改阈值-将是10的幂:10,0001,00010010,{{1} }。
  • 从地图获取字符索引。其简单的阈值数量就适合该值,但不超过地图中的字符数。
  • 计算输入值中剩余的值,然后转到下一个位置

您应该添加验证值,以适合格式化字符串的给定长度。


长度为3的样本

1

输出:

Enumerable.Range(0, 3886).Select(x => x.ToZormat(3))