为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
繁星coding 2022-06-19 16:41:18
我正在尝试创建格式的数字序列,一旦到达我想使用前导字母继续序列。string"99999"例子:"00000" -> "00100" -> "99999" -> "A0001" -> "A9999" -> "B0001" -> "ZZZZZ"有没有简单的方法来实现这一点?到目前为止,我尝试将我string的数字和字母分开,然后如果数字达到最大值,我会检查一些代码,如果它达到可用的最大值,我会添加一个字母。对我来说看起来并不优雅。
查看完整描述

2 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

让我们实现GetNextValue方法:对于给定 value的(例如"A9999"),我们计算下一个("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)


000

001

002

...

009

010

...

999

A01

...

A99

B01

...

Z99

AA1

...

AA9

AB1

...

AZ9

BA1

...

ZZ9

AAA

AAB

AAC

...

AAZ

ABA

...

ZZY

ZZZ


查看完整回答
反对 回复 2022-06-19
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

这是一个扩展方法,它将整数值格式化为您的格式(带前导字母):


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 的字符串时,前导字母会出现在 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))

输出:


000

001

002

...

999

A00

A01

...

A99

B00

B01

...

Z99

ZA0

ZA1

...

ZZ9

ZZA

...

ZZZ


查看完整回答
反对 回复 2022-06-19
  • 2 回答
  • 0 关注
  • 160 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信