簡體   English   中英

C#創建包含數字和字符的字符串序列

[英]C# create string sequence with both number and characters

我正在嘗試以string格式創建一系列數字 ,一旦達到"99999"我想使用前導字母繼續序列。

例:

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

有沒有一種簡單的方法來實現這一目標?

到目前為止,我試圖我的string 分成數字和字母,然后如果數字達到最大值,我會有一些代碼檢查,如果達到最大值,我會添加一個字母。 對我來說看起來不是很優雅。

讓我們實現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

這是一個擴展方法,它將整數值格式化為您的格式(帶有前導字母):

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,000100101
  • 從地圖中獲取角色索引。 它的閾值數量符合數值,但不超過地圖中的字符數。
  • 計算輸入值的剩余部分並轉到下一個位置

您應該為符合格式化字符串的給定長度的最大值添加驗證。


長度為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM