1

可以说我有几个短字符串:

string[] shortStrings = new string[] {"xxx","yyy","zzz"}; (这个定义也可以改变数组和字符串的长度,所以不是固定的)

当给定字符串时,我想检查它是否仅与 shortStrings 结合,如何?

假设功能就像bool TestStringFromShortStrings(string s)

然后

TestStringFromShortStrings("xxxyyyzzz") = true;
TestStringFromShortStrings("xxxyyyxxx") = true;
TestStringFromShortStrings("xxxyyy") = true;
TestStringFromShortStrings("xxxxxx") = true;
TestStringFromShortStrings("xxxxx") = false;
TestStringFromShortStrings("xxxXyyyzzz") = false;
TestStringFromShortStrings("xxx2yyyxxx") = false;

请推荐一种记忆力不紧张且速度较快的方法。

[EIDT] 这个函数有什么用?

我个人会用这个函数来测试一个字符串是否是拼音的组合ok,一些中文的东西。如果您看不懂中文,则跟随中文是一回事。

检测一个字符串是否为汉语拼音(例如检测是否拼音域名) 所有的汉语拼音有:</p>

(检测一个字符串是否是拼音字符串的汉语拼音(例如检测音域):)

Regex PinYin = new Regex(@"^(a|ai|an|ang|ao|ba|bai|ban|bang|bao|bei|ben|beng|bi|bian|biao|bie|bin|bing|bo|bu|ca|cai|can|cang|cao|ce|cen|ceng|cha|chai|chan|chang|chao|che|chen|cheng|chi|chong|chou|chu|chua|chuai|chuan|chuang|chui|chun|chuo|ci|cong|cou|cu|cuan|cui|cun|cuo|da|dai|dan|dang|dao|de|den|dei|deng|di|dia|dian|diao|die|ding|diu|dong|dou|du|duan|dui|dun|duo|e|ei|en|eng|er|fa|fan|fang|fei|fen|feng|fo|fou|fu|ga|gai|gan|gang|gao|ge|gei|gen|geng|gong|gou|gu|gua|guai|guan|guang|gui|gun|guo|ha|hai|han|hang|hao|he|hei|hen|heng|hong|hou|hu|hua|huai|huan|huang|hui|hun|huo|ji|jia|jian|jiang|jiao|jie|jin|jing|jiong|jiu|ju|juan|jue|jun|ka|kai|kan|kang|kao|ke|ken|keng|kong|kou|ku|kua|kuai|kuan|kuang|kui|kun|kuo|la|lai|lan|lang|lao|le|lei|leng|li|lia|lian|liang|liao|lie|lin|ling|liu|long|lou|lu|lv|luan|lue|lve|lun|luo|ma|mai|man|mang|mao|me|mei|men|meng|mi|mian|miao|mie|min|ming|miu|mo|mou|mu|na|nai|nan|nang|nao|ne|nei|nen|neng|ni|nian|niang|niao|nie|nin|ning|niu|nong|nou|nu|nv|nuan|nuo|nun|ou|pa|pai|pan|pang|pao|pei|pen|peng|pi|pian|piao|pie|pin|ping|po|pou|pu|qi|qia|qian|qiang|qiao|qie|qin|qing|qiong|qiu|qu|quan|que|qun|ran|rang|rao|re|ren|reng|ri|rong|rou|ru|ruan|rui|run|ruo|sa|sai|san|sang|sao|se|sen|seng|sha|shai|shan|shang|shao|she|shei|shen|sheng|shi|shou|shu|shua|shuai|shuan|shuang|shui|shun|shuo|si|song|sou|su|suan|sui|sun|suo|ta|tai|tan|tang|tao|te|teng|ti|tian|tiao|tie|ting|tong|tou|tu|tuan|tui|tun|tuo|wa|wai|wan|wang|wei|wen|weng|wo|wu|xi|xia|xian|xiang|xiao|xie|xin|xing|xiong|xiu|xu|xuan|xue|xun|ya|yan|yang|yao|ye|yi|yin|ying|yo|yong|you|yu|yuan|yue|yun|za|zai|zan|zang|zao|ze|zei|zen|zeng|zha|zhai|zhan|zhang|zhao|zhe|zhei|zhen|zheng|zhi|zhong|zhou|zhu|zhua|zhuai|zhuan|zhuang|zhui|zhun|zhuo|zi|zong|zou|zu|zuan|zui|zun|zuo)+$");

用下面的正则表达式方法,效果轻松了,而且很简单,就是对慢(最擅长的方式)长字符串比较,解决内存溢出</p>

(用正则表达式试了一下:最简单,效果也很好,就是有点慢。长字符串上的递归方式太麻烦了,太容易溢出栈了。)

4

3 回答 3

4

编辑:多亏了LB和millimoose,这大大简化了。

正则表达式来拯救!使用System.Text.RegularExpressions.Regex,我们得到:

public static bool TestStringFromShortStrings(string checkText, string[] pieces) {
    // Build the expression.  Ultimate result will be
    // of the form "^(xxx|yyy|zzz)+$".
    var expr = "^(" + 
               String.Join("|", pieces.Select(Regex.Escape)) + 
               ")+$";

    // Check whether the supplied string matches the expression.
    return Regex.IsMatch(checkText, expr);
}

这应该能够正确处理具有不同长度的多个重复模式的情况。例如,如果您可能的片段列表包括字符串"xxx""xxxx".

于 2012-08-02T21:42:43.023 回答
2

将目标字符串复制到字符串生成器。对于短字符串数组中的每个字符串,从目标中删除所有出现。如果你以零长度字符串结束,则为真,否则为假。

编辑:这种方法是不正确的。请参考评论。保持这个答案仍然在这里,因为它最初看起来相当正确。

于 2012-08-02T21:38:48.163 回答
2

您可以将输入字符串的开头与每个短字符串进行比较。一旦你有一个匹配,你拿起其余的字符串并重复。一旦你没有更多的字符串,你就完成了。例如:

string[] shortStrings = new string[] { "xxx", "yyy", "zzz" };

bool Test(string input)
{
    if (input.Length == 0)
        return true;

    foreach (string shortStr in shortStrings)
    {
        if (input.StartsWith(shortStr))
        {
            if (Test(input.Substring(shortStr.Length)))
                return true;
        }
    }
    return false;
}

您可以通过删除递归或通过对短字符串进行排序并执行二进制而不是线性搜索来优化它。


这是一个非递归版本,它使用Stack对象来代替。没有机会获得StackOverflowException

string[] shortStrings = new string[] { "xxx", "yyy", "zzz" };

bool Test(string input)
{
    Stack<string> stack = new Stack<string>();
    stack.Push(input);

    while (stack.Count > 0)
    {
        string str = stack.Pop();
        if (str.Length == 0)
            return true;
        foreach (string shortStr in shortStrings)
        {
            if (str.StartsWith(shortStr))
                stack.Push(str.Substring(shortStr.Length));
        }
    }
    return false;
}
于 2012-08-02T21:42:15.683 回答