C# Pure string parse, no stack


  • 0
    J
    public class Solution {
    
            public bool IsValid(string code)
            {
                if (string.IsNullOrEmpty(code)) return false;          
    
                string content; int rightStartIndex;
                
                if (!ValidateClosedTags(code, true, out content, out rightStartIndex))
                {
                    return false;
                }
                return ValidateContent(content);
            }
    
            static bool ValidateContent(string c)
            {
                string cheader = "<![CDATA[";
                string cend = "]]>";
                // remove cdata
                while (true)
                {
                    int index = c.IndexOf(cheader);
                    if (index >= 0)
                    {
                        int p = c.IndexOf(cend, index);
                        if (p < 0)
                        {
                            return false;
                        }
                        else
                        {
                            c = c.Substring(0, index) + c.Substring(p + 3);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
    
                if (c.IndexOf("<") >= 0)
                {
                    string newcontent;
                    int rightpart = 0;
    
                    if (!ValidateClosedTags(c, false, out newcontent, out rightpart))
                    {
                        return false;
                    }
                    else
                    {
                        return (ValidateContent(newcontent) && ValidateContent(c.Substring(rightpart)));
                    }
                }
                return true;
            }
    
            static bool ValidateClosedTags(string c, bool isRoot, out string content, out int rightStartIndex)
            {
                content = "";
                rightStartIndex = 0;
                try
                {
                    // isParent indicate if current tag should be Parent tag, say: <A> <A> </A> </A>
                    // we need to parse to the last </A> when current tag is parent
                    bool isParent = isRoot;
                    int s1 = c.IndexOf("<");
                    int s2 = c.IndexOf(">");
    
                    string stag = c.Substring(s1 + 1, s2 - s1 - 1);
                    string fullstartTag = "<" + stag + ">";
    
                    if (!ValidateTags(stag)) return false;
    
                    string endTag = "</" + stag + ">";
    
                    int e1 = c.IndexOf(endTag, s2);
    
                    // find <A> <A> </A> </A>
                    // then the first </A> is not correct
                    // if contains <A> inside the <A> ... </A>, current tag must be parent
                    if (c.IndexOf(fullstartTag, s2, e1 - s2 - 1) >= 0)
                    {
                        isParent = true;
                    }
    
                    if (isParent)
                    {
                        e1 = c.LastIndexOf(endTag);
                    }
    
                    if (e1 < s2)
                    {
                        return false;
                    }
    
                    if (isRoot)
                    {
                        if (s1 != 0 || !c.EndsWith(endTag))
                        {
                            return false;
                        }
                    }
    
                    content = c.Substring(s2 + 1, e1 - s2 - 1);
                    rightStartIndex = e1 + endTag.Length;                
                }
                catch
                {
                    return false;
                }
    
                return true;
            }
    
            static bool ValidateTags(string Tag)
            {
                string[] special = new string[] { "<", ">", "/", "!", "[", "]" , " "};
                string[] digit = new string[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
                try
                {
                    if (string.IsNullOrEmpty(Tag)) return false;                   
    
                    foreach (string s in special)
                    {
                        if (Tag.Contains(s)) return false;
                    }
    
                    foreach (string s in digit)
                    {
                        if (Tag.Contains(s)) return false;
                    }
    
                    if (Tag.Length > 9 || Tag.Length < 1) return false;
                   
                    if (Tag.ToUpper() == Tag)
                    {
                        return true;
                    }                
                }
                catch
                {
                    return false;
                }
    
                return false;
            }
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.