Home > Back-end >  How to split the same string depending on its characters?
How to split the same string depending on its characters?

Time:08-28

I want to be able to create an array of characters as strings, from a given string. Characters between () should be 1 element, and each character outside the () should be counted likewise. So a string like:

string test = "(af)sd(abc)abc"

would generate an array that look like this:

string[] testSplitted = { "af", "s", "d", "abc", "a", "b", "c" };

The code below is only able to make the characters inside the () items of the array but not the characters outside the (). So instead I get:

string[] testSplitted = { "af", "sd", "abc", "abc" };
 public static string[] transmissions = { "(ab)(bc)(ca)", "abc", "(abc)(abc)(abc)", "(zyx)bc" };
 public static string[] words = { "abc", "bca", "dac", "dbc", "cba" };

 public static void Main()
        {
            for (int y = 0; y < N; y  )
            {
                string[] charSplit = transmissions[y].Replace("(", "").Replace(")", "").Split();
                int K = 0;
                foreach (var item in words)
                {
                    int matches = 0;
                    for (int i = 0; i < item.Length; i  )
                    {
                        if (!charSplit[i].Contains(item[i])) { break; }
                        matches  ;
                    }
                    if (matches == 3) { K  ; }
                }
                Console.WriteLine("Case #"   (y   1)   ": "   K);
            }
        }

Is there anyway I can split the characters outside of the () to separate elements aswell?

CodePudding user response:

Here's a pretty simple state machine that's O(n).

public static IEnumerable<string> StringWalker(string input)
{
    bool inParens = false;
    StringBuilder buffer = new StringBuilder();
    List<string> result = new List<string>();

    foreach (var c in input)
    {
        if (c == '(')
        {
            if (inParens)
            {
                throw new Exception("Nested Parens not allowed");
            }
            inParens = true;
            buffer.Clear();
        }
        else if (inParens)
        {
            if (c == ')')
            {
                inParens = false;
                result.Add(buffer.ToString());
            }
            else
            {
                buffer.Append(c);
            }
        }
        else
        {
            result.Add(c.ToString());
        }
    }
    return result;
}

The results look like:

abc(de)(fgh)ijk:  ==>  (a) (b) (c) (de) (fgh) (i) (j) (k) 
(abc)de(f)gh(ijklm)nop:  ==>  (abc) (d) (e) (f) (g) (h) (ijklm) (n) (o) (p)

CodePudding user response:

You can try using reguar expressions and Match all the items:

using System.Linq;
using System.Text.RegularExpressions;

...

string test = "(af)sd(abc)abc";

string[] testSplitted = Regex
  .Matches(test, @"\(.*?\)|.")
  .Cast<Match>()
  .Select(match => match.Value.Trim('(', ')'))
  .ToArray();

More tests:

string[] tests = new string[] {
  "(ab)(bc)(ca)", 
  "abc", 
  "(abc)(abc)(abc)", "(zyx)bc" 
};

static string[] Perform(string value) => Regex
  .Matches(value, @"\(.*?\)|.")
  .Cast<Match>()
  .Select(match => match.Value.Trim('(', ')'))
  .ToArray();

string report = string.Join(Environment.NewLine, tests
  .Select(test => $"{test,15} => {string.Join(", ", Perform(test))}"));

Console.Write(report);

Output:

   (ab)(bc)(ca) => ab, bc, ca
            abc => a, b, c
(abc)(abc)(abc) => abc, abc, abc
        (zyx)bc => zyx, b, c

Please, fiddle yourself

  • Related