用于字符串转换的原位算法

时间:2014-03-09 18:54:23

标签: c# algorithm linq

给定一个字符串,将所有数字元素移动到字符串的末尾。在移动元素时,保持所有定位元素的相对顺序相同。

例如,如果给定的字符串是

  

a1b2c3d4e5f6g7h8i9j1k2l3m4

将其转换为

  

abcdefghijklm1234567891234

就地和O(n)时间复杂度。

我得到了不同的结果

  

abcdefghijklm7481951326324

我也没能测试另一个字符串

  

aHR0cDovL3d3dy5nZWVrc2ZvcmdlZWtzLm9yZy9hbi1pbi1wbGFjZS1hbGdvcml0aG0tZm9yLXN0cmluZy10cmF

代码:

    static string s = "a1b2c3d4e5f6g7h8i9j1k2l3m4";
    static void Main(string[] args)
    {
        char[] input = s.ToCharArray();
        string output = arrangeList(input);
        Console.WriteLine(output);
        Console.WriteLine("Another test");
        s = "aHR0cDovL3d3dy5nZWVrc2ZvcmdlZWtzLm9yZy9hbi1pbi1wbGFjZS1hbGdvcml0aG0tZm9yLXN0cmluZy10cmF";
        input = s.ToCharArray();
        output = arrangeList(input);
        Console.WriteLine(output);
        Console.Read();
    }

    private static string arrangeList(char[] x)
    {
        for (int i = 1; i < x.Length - 1; i++)
        {
            int j = i + 1;
            while (j < x.Length)
            {
                if ( (x[j] > '0' && x[j] < '9') && x[i] > '9')
                {
                    swap(x, i, j); j++;
                    break;
                }
                if ( (x[i] > '0' && x[i] < '9') && x[j] > '9')
                {
                    swap(x, i, j); j++;
                    break;
                }
                j++;
            }
        }
        return new string(x);
    }
    private static void swap(char[] a, int i, int j)
    {
        char temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

4 个答案:

答案 0 :(得分:3)

使用Linq

var input = "a1b2c3d4e5f6g7h8i9j1k2l3m4";
var output = String.Join("", input.GroupBy(c => char.IsDigit(c))
                                  .OrderBy(x => x.Key) //Always 2 items to sort. Not O(N*logN)
                                  .SelectMany(g => g));

答案 1 :(得分:1)

您可以通过从后面复制数字和从前面复制字母来轻松地在字符数组中构建它。那就是:

var input = "a1b2c3d4e5f6g7h8i9j1k2l3m4";
int ixLetter = 0;
int ixDigit = input.Length - 1;
int oxLetter = 0;
int oxDigit = input.Length - 1;

char[] output = new char[input.Length];
while (ixDigit >= 0)
{
    if (char.IsDigit(input[ixDigit]))
    {
        output[oxDigit] = input[ixDigit];
        --oxDigit;
    }
    if (!char.IsDigit(input[ixLetter]))
    {
        output[oxLetter] = input[ixLetter];
        ++oxLetter;
    }
    --ixDigit;
    ++ixLetter;
}

string result = new string(output);

这会在字符串上进行两次传递,一次来自前面,一次来自后面。复杂性是线性的,因此是O(n)。

现在,一次性完成......我不得不考虑一下。

答案 2 :(得分:1)

这有效,使用linq,并且具有O(n)时间复杂度:

var input = @"123vcvcv00191pololo";
var array =
    input
        .ToCharArray()
        .Where(c => !Char.IsDigit(c))
        .Concat(
            input
                .ToCharArray()
                .Where(c => Char.IsDigit(c)))
        .ToArray();
var output = new String(array);

Console.Write(output);
// vcvcvpololo12300191 

答案 3 :(得分:0)

使用linq的OrderBy如图所示,应将所有数字移动到字符串/ char []的末尾,按照它们出现在字符串中的顺序。

var input  = @"123vcvcv00191pololo";
var array  = input.ToCharArray().OrderBy(c => Char.IsDigit(c)).ToArray();
var output = new String(array);

Console.Write(output);
//vcvpololo12300191