如何使用 C# 对连续的字母数字字符串进行排序和组合到范围中 [关闭]

问题描述 投票:0回答:1

我正在尝试编写一个 C# 程序,对字母数字字符串列表进行排序并将连续的数值组合到范围中。

我会有一个字符串列表 例如。

“0P228PBC”、“0P229PBC”、“0P230PBC”。

它们需要合并到

0P228PBC~0P230PBC

但如果它们之间的差值仅为 1,则不需要波浪符号。 例如。

“0P228PBC”、“0P229PBC”。

它们需要合并到

“0P228PBC”、“0P229PBC”。

另一种可能是

“AB999B”、“AC000B”、“AC001B”

然后它们应该合并到

AB999B~AC001B

因为999+2变成了AB->AC

例如,给定列表:

"0n7asd1112", "0n7asd1113", "0N7P1ABC", "0N7P2ABC", "0N7P3ABC", "0P228PBC", "0P229PBC", "0P230PBC", "62700001", "62700002", "627000010", "ab51561aa", "ab51561ab", "ab51561ac","AB999B","AC000B","AC001B"

我想得到的输出为:

"0n7asd1112","0n7asd1113", "0N7P1ABC~0N7P3ABC", "0P228PBC~0P230PBC", "62700001","62700002", "627000010", "ab51561aa~ab51561ac","AB999B~AC001B"

我在实现所需输出方面面临问题,特别是在将连续值正确组合到范围中时。

任何人都可以提供指导、建议或更好的方法来实现这一目标吗?

提前非常感谢!

我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace SortTest
{
    internal class Program
    {
        public static int AlphanumericCompare(string a, string b)
        {
            var regex = new Regex("([0-9]+)|([a-zA-Z]+)");
            var matchesA = regex.Matches(a);
            var matchesB = regex.Matches(b);

            int i = 0;

            while (i < matchesA.Count && i < matchesB.Count)
            {
                var matchA = matchesA[i];
                var matchB = matchesB[i];

                if (matchA.Value.All(char.IsDigit) && matchB.Value.All(char.IsDigit))
                {
                    var numA = int.Parse(matchA.Value);
                    var numB = int.Parse(matchB.Value);

                    if (numA != numB)
                        return numA.CompareTo(numB);
                }
                else
                {
                    var strCompare = string.Compare(matchA.Value, matchB.Value, StringComparison.OrdinalIgnoreCase);
                    if (strCompare != 0)
                        return strCompare;
                }

                i++;
            }

            if (i < matchesA.Count) return 1;
            if (i < matchesB.Count) return -1;

            return 0;
        }

        public static string GenerateRange(IEnumerable<string> sortedList)
        {
            List<string> output = new List<string>();
            string start = null;
            string end = null;

            foreach (var s in sortedList)
            {
                if (start == null)
                {
                    start = s;
                    end = s;
                    continue;
                }

                if (AlphanumericCompare(Increment(end), s) == 0)
                {
                    end = s;
                }
                else
                {
                    output.Add(start == end ? start : $"{start}~{end}");
                    start = s;
                    end = s;
                }
            }

            // Handle the last range
            output.Add(start == end ? start : $"{start}~{end}");

            return string.Join(" ", output);
        }

        public static string Increment(string input)
        {
            var regex = new Regex("([0-9]+)$");
            var match = regex.Match(input);
            if (match.Success)
            {
                var num = int.Parse(match.Value) + 1;
                return regex.Replace(input, num.ToString());
            }
            else
            {
                return input + "1";
            }
        }

        static void Main(string[] args)
        {
            var items = new List<string>
        {
            "0n7asd1112", "0n7asd1113", "0N7P1ABC", "0N7P2ABC", "0N7P3ABC",
            "0P228PBC", "0P229PBC", "0P230PBC", "62700001", "62700002",
            "627000010", "ab51561aa", "ab51561ab", "ab51561ac","AB999B","AC000B","AC001B"
        };

            var sortedItems = items.OrderBy(x => x, Comparer<string>.Create(AlphanumericCompare));
            var result = GenerateRange(sortedItems);

            Console.WriteLine(result);
        }
    }
}

运行输出:

"0n7asd1112~0n7asd1113 0N7P1ABC 0N7P2ABC 0N7P3ABC 0P228PBC 0P229PBC 0P230PBC 62700001~62700002 627000010 AB999B ab51561aa ab51561ab ab51561ac AC000B AC001B"
c# algorithm sorting
1个回答
0
投票

您可以这样对它们进行排序:

    public static async Task Main()
    {
        var inputs = new[]
        {
            "0n7asd1112", "0n7asd1113", "0N7P1ABC", "0N7P2ABC", "0N7P3ABC", "0P228PBC", "0P229PBC", "0P230PBC",
            "62700001", "62700002", "627000010", "ab51561aa", "ab51561ab", "ab51561ac", "AB999B", "AC000B", "AC001B"
        };

        foreach (var a in inputs.Select(x => new SplitDto(x)).OrderBy(x => x))
        {
            Console.WriteLine(a.Original);
        }
    }



    public sealed class SplitDto : IComparable<SplitDto>
    {
        private readonly string _input;
        private readonly List<IComparable> _forCompare;

        public SplitDto(string input)
        {
            _input = input;
            _forCompare = Regex.Matches(input, "(?<Alpha>[a-zA-Z]+)|(?<Numeric>[0-9]+)")
                .Where(x=> !string.IsNullOrWhiteSpace(x.Value))
                .Select(x => x.Groups["Alpha"].Success ? (IComparable)x.Value : long.Parse(x.Value)).ToList();
        }
        
        public int CompareTo(SplitDto other)
        {
            if (ReferenceEquals(this, other)) return 0;
            if (ReferenceEquals(null, other)) return 1;
            
            var cmp = _forCompare.Count.CompareTo(_forCompare.Count);
            if (cmp != 0)
                return cmp;

            for (int i = 0; i < _forCompare.Count; i++)
            {
                if (_forCompare[i].GetType() != other._forCompare[i].GetType())
                {
                    cmp = _forCompare[i].ToString().CompareTo(other._forCompare[i].ToString());
                    if (cmp != 0)
                        return cmp;
                }
                else
                {
                    cmp = _forCompare[i].CompareTo(other._forCompare[i]);
                    if (cmp != 0)
                        return cmp;
                }

            }
            return 0;
        }

        public int CompareTo(object obj)
        {
            if (ReferenceEquals(null, obj)) return 1;
            if (ReferenceEquals(this, obj)) return 0;
            return obj is SplitDto other ? CompareTo(other) : throw new ArgumentException($"Object must be of type {nameof(SplitDto)}");
        }
    }

输出:

0n7asd1112
0n7asd1113
0N7P1ABC
0N7P2ABC
0N7P3ABC
0P228PBC
0P229PBC
0P230PBC
62700001
62700002
627000010
ab51561aa
ab51561ab
ab51561ac
AB999B
AC000B
AC001B

分组我稍后会发布。

© www.soinside.com 2019 - 2024. All rights reserved.