1

Given an input string (such as D4C3B2A1) I want to sort the alphabet characters, and the numbers (ascending) then alternate them. Expected output would be: A1B2C3D4

The way I thought about doing this was using RegEx to pull out two strings, letters only, then numbers only.

Sorting both strings, then using substring to pull out each letter one by one and assigning it a new string. However, this seems like it would only work given you know orignal strings value/length etc.

Plus I figured there was a better way to do this to begin with.

Assume this needs to work for inputted string, not just the provided example string.

4
  • What if the input is abc1278d? or a4b3c2d1? Your example doesn't help much, it looks like a1 is a single letter... Commented Sep 2, 2010 at 12:25
  • For clarification, abc1278d = a1b2c7d8 and a4b3c2d1 = a1b2c3d4 - sorry. Alternate each letter and number. Commented Sep 2, 2010 at 12:26
  • Are you sure you have always the same number of digits and letters ? Commented Sep 2, 2010 at 12:30
  • Assume, input will actually be masked to: letter-number-letter-number-letter-number-letter-number So Kobi's first example wouldn't be a valid input actually. Commented Sep 2, 2010 at 12:36

3 Answers 3

2

To get (sorted) strings of letters and numbers you don't need regex, use Linq:

string s = "D4C3B2A1";

string letters = new String(s.Where(Char.IsLetter).OrderBy(c=>c).ToArray());
string numbers = new String(s.Where(Char.IsNumber).OrderBy(c=>c).ToArray());

To mix the two, you could use this:

public static string Mix(string s1, string s2)
{
    if (String.IsNullOrEmpty(s1))
        return s2;

    if (String.IsNullOrEmpty(s2))
        return s1;

    string s = String.Empty;

    for (int i=0; i<Math.Min(s1.Length, s2.Length); i++)
    {
        s += s1[i].ToString() + s2[i].ToString();
    }

    if (s1.Length > s2.Length)
        s += s1.Substring(s2.Length);
    else if (s2.Length > s1.Length)
        s += s2.Substring(s1.Length);

    return s;
}
Sign up to request clarification or add additional context in comments.

Comments

2

(Untested)

public static string Transform(string text)
{
  // Insert null-check here. You may also want to trim the string.

  var letters = text.Where(char.IsLetter).OrderBy(l => l).ToArray();
  var numbers = text.Where(char.IsNumber).OrderBy(n => n).ToArray();

  if (letters.Length != numbers.Length || (letters.Length + numbers.Length != text.Length))
       throw new FormatException("Text must consist only of an equal number of letters and numbers.");

  var zipped = letters.Zip(numbers, (l, n) => string.Concat(l, n));
  return string.Concat(zipped.ToArray());
}

If you are on .NET 3.5, you can replace the zipping line with:

var zipped = Enumerable.Range(0, text.Length).Select(i => string.Concat(letters[i], numbers[i]));

Comments

0

Supposing to have same numbers of digits and letters (i've tested it):

string s = "D4C1B2A3";

var s1 = s.Where(c => char.IsLetter(c)).OrderBy(c => c).ToArray();
var s2 = s.Where(c => char.IsDigit(c)).OrderBy(c => c).ToArray();

var sortedString = new string(s.Select((x, idx) => idx % 2 == 0 ? s1[idx / 2] : s2[(idx - 1) / 2]).ToArray());

To avoid "improper" use of s.Select you can change the last line with:

var sortedString = new string(Enumerable.Range(0, s.Length).Select(idx => idx % 2 == 0 ? s1[idx / 2] : s2[(idx - 1) / 2]).ToArray());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.