保持前导零的情况下递增字符串

3

我需要一个算法来生成一组库存商品序列号,从起始序列开始工作。

例如,如果起始序列为B10S001,并且要生成3个数字,则结果应为-

B10S001
B10S002
B10S003

然而,以起始序列B10S998开始,并生成3个数字,结果应为 -
B10S998
B10S999
B10T000

即数字的数量必须保持不变,如果必要的话,最后一个字母会递增。

注意 - 我不知道第一个序列号的结构。它可以是任意长度和任何字母数字组合。

我目前正在使用的代码是:

public static string IncrementNumber(string pNumber) {
    string newNum = "";
    var match = Regex.Match(pNumber, @"(?<=(\D|^))\d+(?=\D*$)");
    if (match.Success) {
        var number = int.Parse(match.Value) + 1;
        newNum = string.Format(
            "{0}{1}{2}",
            pNumber.Substring(0, match.Index),
            number,
            pNumber.Substring(match.Index + match.Length));
        }
    return newNum;
}

这让我有些进展,但删除了前导零,并且没有增加字母。我不太了解正则表达式(从论坛帖子中复制了上面的代码)- 有什么想法可以实现这一点吗?


哪种语言?使用Perl可以吗? - Vijay
sarathi - 在 .net 3.5 上使用 C#。如果要加入 Perl,会有多难?(只要不会引起任何部署问题,我很乐意使用它) - Andrew Austin
抱歉 - 应该提到,列出的示例可能不一定是使用的序列号结构。本质上,我需要适应起始序列号提供的任何字母和数字长度,然后查看最右边的数字和字母以应用逻辑? - Andrew Austin
被标记为Java;另外,B10S999后面是B10T001而不是B10T000,这正常吗? - UmNyobe
umnyobe - 是的,非常正确,溢出应该是B10T000,而不是B10T001 - 感谢指出。 - Andrew Austin
3个回答

1

假设您有整数值和字母,这里是一些伪代码,告诉您需要做什么:

fun CreateSerial(value, letter):
  value = value + 1
  if value == 1000:
    letter = letter + 1
    if letter > 'Z':
      letter = 'A'
  if value < 10:
    return "B10" + letter + "00" + value
  else if value < 100:
    return "B10" + letter + "0" + value
  else:
    return "B10" + letter + value

编辑:以下是不使用模式匹配进行操作的伪代码。

fun IncrementSerial(serial):
  IncrementNext(serial, serial.length - 1)

fun IncrementNext(serial, index):
  if index == 0:
    return
  if serial[index - 1] is numeral:
    IncrementNumeral(serial, index - 1)
  else:
    IncrementAlpha(serial, index - 1)

fun IncrementNumeral(serial, index):
  number = serial[index] + 1
  if number > '9':
    number = '0'
    IncrementNext(serial, index - 1)
  serial[index] = number

fun IncrementAlpha(serial, index):
  alpha = serial[index] + 1
  if alpha > 'Z':
    alpha = 'A'
    IncrementNext(serial, index - 1)
  serial[index] = alpha

本质上,我们从末尾开始递增字母,如果溢出,则重置该字母并继续下一个,每次迭代都检查其类型(数字 vs 字母)。

如果达到最大序列号,它将返回,可选择重置所有内容。


谢谢 - 我现在正在尝试这个,看看能否得到结果。 - Andrew Austin
使用这种方法构建了一个类,目前运行良好 - 谢谢。 - Andrew Austin

1

您需要手动实现加法,就像在纸上进行长加法一样。首先,您需要将字符串视为数字,其中每个数字位于不同的基础上。第三个从右边开始的数字位于10进制基础上,最右边的字母位于26进制基础上,然后是两个10进制数字,然后可能是另一个26进制数字。

现在,您可以开始逐个递增数字,从右边开始。取最右边的数字并将其增加1。如果没有溢出(也就是说,您没有从9变成0),则完成了。如果有溢出,则该数字返回到0,并且您需要将该数字递增到其左侧。

当您到达B10S999时,您会递增最右边的数字并得到一个溢出。然后您会递增右数第二个数字并得到一个溢出。然后是下一个数字并得到一个溢出。现在您必须递增S。下一个字母是T,因此您会得到B10T000。

当您到达B10Z999并递增时,您将得到四个溢出,并以B11A000结束。


谢谢 - 我希望在 .net / regex 中有一些内置函数,而不是“手动”选项,但看起来这将是前进的方式。Dicarlo2 的伪代码看起来是相同的逻辑 - 我将尝试实现类似这样的东西,看看是否能得到结果。 - Andrew Austin

0
为什么不把所有的逻辑都放在一个类中,然后就完成了呢?显然你的串口有4个部分。
 class Serial{
     Serial(string s);

     char prefixLetter;
     int prefixNum;
     char middleLetter;
     int traillingNum;

     void increment();
     bool isvalid();
     string toString();

     //etc....
 }

抱歉 - 我应该提到我不一定知道第一个序列的结构 - 客户可能希望使用任何作为基础序列号的东西。 - Andrew Austin
哦,好的,明白了...你能更新一下吗? - UmNyobe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接