首页 > 解决方案 > 计算下一个字符串的函数

问题描述

我需要一个函数来获取下一个字符串,但这里的逻辑不同。我想将输入字母 A 增加到 B,B 到 C 直到 Z。但是在 ZI 之后需要获取字符串 A1。当我将字符串 A1 作为输入时,它需要递增到 B1,B1 到 C1 直到 Z1。Z1之后我应该得到A2。当我得到 A2 时,它应该将其增加到 B2,依此类推,直到 Z9。有人可以帮忙吗。

我尝试使用下面的代码,但是当我输入 A1 时它给了我错误的输出,它给我的输出为 A2。

我试过的:

public static string Increment(string input){
  List<char> chars = input.ToList();
  for (int i = chars.Count - 1; i >= 0; i++)
  {
    if (chars[i] < '1' || chars[i] > '9')
    {
      throw new ArgumentException("");
    }
    chars[i]++;
    if (chars[i] > 'Z')
    {
      chars[i] = 'A';
      if (i == 0)
      {
        chars.Add('1');
      }
    }
    else
    {
      break;
    }
  }
  return string.concat(chars);
}

标签: c#

解决方案


我发现创建一个类型来处理这类事情总是有帮助的。

这是一个带有一些基本操作的简单结构:

笔记!整个事情还没有经过彻底的测试。

public struct AlphaNumericId : IEquatable<AlphaNumericId>, IComparable<AlphaNumericId>
{
    private static readonly Regex _ParsePattern = new Regex(@"^(?<letter>[A-Z])(?<number>\d*)$");
    private readonly int _Value;

    public AlphaNumericId(int value)
    {
        if (value < 0)
            throw new ArgumentOutOfRangeException(nameof(value), "value cannot be negative");

        _Value = value;
    }

    public override string ToString()
    {
        int letter = _Value % 26;
        int number = _Value / 26;

        var sb = new StringBuilder(5);
        sb.Append((char)('A' + letter));
        if (number > 0)
            sb.Append(number);
        return sb.ToString();
    }

    public static AlphaNumericId Parse(string input)
    {
        if (TryParse(input, out var value))
            return value;
        throw new FormatException($"Unable to parse '{input}' as an AlphaNumericId");
    }

    public static bool TryParse(string input, out AlphaNumericId value)
    {
        value = default;

        var match = _ParsePattern.Match(input);
        if (!match.Success)
            return false;
        
        char letter = match.Groups["letter"].Value[0];
        string letterString = match.Groups["number"].Value;
        int number = 0;
        if (letterString.Length > 0)
            if (!int.TryParse(letterString, out number))
                return false;
                
        value = new AlphaNumericId(number * 26 + (letter - 'A'));
        return true;
    }

    public static AlphaNumericId operator ++(AlphaNumericId input) => new AlphaNumericId(input._Value + 1);
    public static AlphaNumericId operator --(AlphaNumericId input) => new AlphaNumericId(input._Value - 1);

    public static AlphaNumericId operator +(AlphaNumericId input, int offset) => new AlphaNumericId(input._Value + offset);
    public static AlphaNumericId operator -(AlphaNumericId input, int offset) => new AlphaNumericId(input._Value - offset);
    public static int operator -(AlphaNumericId input, AlphaNumericId other) => input._Value - other._Value;
    
    public static bool operator <(AlphaNumericId a, AlphaNumericId b) => a._Value < b._Value;
    public static bool operator >(AlphaNumericId a, AlphaNumericId b) => a._Value > b._Value;
    public static bool operator ==(AlphaNumericId a, AlphaNumericId b) => a._Value == b._Value;
    public static bool operator !=(AlphaNumericId a, AlphaNumericId b) => a._Value != b._Value;

    public override int GetHashCode() => _Value.GetHashCode() ^ 37;
    public override bool Equals(object obj)
    {
        if (obj is AlphaNumericId other)
            return Equals(other);
        return false;
    }
    
    public bool Equals(AlphaNumericId other) => _Value == other._Value;
    public int CompareTo(AlphaNumericId other) => _Value.CompareTo(other._Value);

    public static explicit operator int(AlphaNumericId id) => id._Value;
    public static explicit operator AlphaNumericId(int value) => new AlphaNumericId(value);
}

“下一个”方法只是:

return (AlphaNumericId.Parse(input) + 1).ToString();

或者您可以简单地将整个内容一直保存在 AlphaNumericId 类型中,然后下一个值将是以下任一值:

input += 1;
input++;

由于该类型还允许与整数相互转换,因此这里是前 100 个 id:

Enumerable.Range(0, 100).Select(i => (AlphaNumericId)i)

这将产生A, B, C, D, ..., Z, A1, A2, ..., Z2, ..., V3


推荐阅读