黑马程序员技术交流社区

标题: 字符串搜索问题 [打印本页]

作者: 亚伦    时间: 2014-5-12 12:01
标题: 字符串搜索问题
本帖最后由 亚伦 于 2014-5-12 21:49 编辑

例如给定一个字符串如 Photo_[1,2]写一个可以检查出这个字符串中出现的第一个子字符串 [数字, 数字],并返回 [ 的索引,找不到返回负一的方法,如本例将返回 [ 的索引 6。
这个函数必须能处理更复杂的逻辑:
例如 [Photo]_[9999,1],返回索引 8 而不是0!
而对于 [a, 1] 或 [99] 则返回 -1

作者: continue     时间: 2014-5-12 14:20
看了很久,慢复杂的,如果通过字符串进行匹配获得的话,我没有想到什么好办法,因为你中键的数字的位数是不定的,可能其他人有办法。我用正则表达式做的,不知道行不
            string str1 = "abaacd_[787,34]abc";
            Regex reg = new Regex(@"(\[(\d)+,(\d)+\])");
            Match match = reg.Match(str1);
            if (match.Success)
            {
                int index = match.Groups[0].Index;
                string str = match.Groups[0].Value;
                Console.WriteLine("匹配的索引为:" + index);
                Console.WriteLine("匹配的值为:" + str);
            }

            //先对正则表达式库进行引用:System.Text.RegularExpressions
            //结果为
            //    匹配的索引为:7
            //    匹配的值为:[787,34]
作者: continue     时间: 2014-5-12 14:57
这个是通过截取字符串实现的
static void GetIndex2 ()
        {
            string str = "abaacd_[787,34]abc[787,34]gg";
            int start=0;
            int mid = 0;
            int end = 0;
            //如果没有找到的话  返回的是-1
            start = str.IndexOf('[', 0);
            if (start > 0)
            {
                mid = str.IndexOf(',', start);
            }
            if (mid > 0)
            {
                end = str.IndexOf(']', mid);
            }
            //判断,这三个关键的是否都存在
            while (start >=0 && mid >0 && end>0)
            {
                string str1 = str.Substring(start+1, mid - start-1);
                string str2 = str.Substring(mid+1, end - mid-1);//中间有个逗号,故要减去1
                int num1, num2;
                if (int.TryParse(str1, out num1) && int.TryParse(str2, out num2))
                {
                     Console.WriteLine("匹配的索引为:" + start);
                     Console.WriteLine("匹配的值为:" + "["+str1+","+str2+"]");
                     break;//如果要输出所有的话,将这个break给注释掉
                }
                else//如果要找到所有的,把这个else注释,就是了下面的代码不动
                {
                    if (end > 0)
                    {
                        start = str.IndexOf('[', end);
                    }
                    if (start > 0)
                    {
                        mid = str.IndexOf(',', start);
                    }
                    if (mid > 0)
                    {
                        end = str.IndexOf(']', mid);
                    }
                }
            }
        }


结果为:
匹配的索引为:7
匹配的值为:[787,34]
匹配的索引为:18
匹配的值为:[787,34]

作者: 西瓜    时间: 2014-5-12 14:57
本帖最后由 西瓜 于 2014-5-12 14:59 编辑

想一想在做
作者: 赵贺景    时间: 2014-5-12 19:51
挺有难度的
作者: 王运波    时间: 2014-5-12 21:38
    确实 有点难度。
作者: 亚伦    时间: 2014-5-12 21:46
  1.         static void Main(string[] args)
  2.         {
  3.             Console.WriteLine("Photo_[1, 2] = {0}", IndexOfParameterList("Photo_[1, 2]"));
  4.             Console.WriteLine("[Photo]_[9999,1] = {0}", IndexOfParameterList("[Photo]_[9999,1]"));
  5.             Console.WriteLine("[Photo]_[999[9,1] = {0}", IndexOfParameterList("[Photo]_[999[9,1]"));
  6.             Console.WriteLine("[a, 1] = {0}", IndexOfParameterList("[a, 1]"));
  7.             Console.WriteLine("[99] = {0}", IndexOfParameterList("[99]"));
  8.             Console.WriteLine("[,] = {0}", IndexOfParameterList("[,]"));
  9.         }
复制代码
  1.         private static int IndexOfParameterList(string s)
  2.         {
  3.             int n1, n2; // 代表参数列表的2个参数

  4.             // 搜索第一个‘['所在的索引
  5.             int indexOfLeftParenthesis = s.IndexOf('[');
  6.             int indexOfRightParenthesis = -1;
  7.             bool isStringHaveParameterList = false;

  8.             // 如果能搜索到‘[',尝试搜索‘]’
  9.             if (indexOfLeftParenthesis != -1)
  10.             {
  11.                 indexOfRightParenthesis = s.Substring(indexOfLeftParenthesis).IndexOf(']');

  12.                 // 如果搜索到‘]’,isStringHaveParameterList为true
  13.                 isStringHaveParameterList = indexOfRightParenthesis != -1;
  14.             }

  15.             // 截取一个从‘[’开始的字符串
  16.             string startLeftParenthesis = s.Substring(indexOfLeftParenthesis); ;
  17.             // 用于从startLeftParenthesis中截取参数列表
  18.             string brackets;

  19.             #region 如果s包含参数列表,判断s是否有包含格式正确的参数列表
  20.             while (isStringHaveParameterList == true)
  21.             {
  22.                 brackets = startLeftParenthesis.Substring(0, startLeftParenthesis.IndexOf(']') + 1);

  23.                 #region 如果参数列表没有","
  24.                 if (brackets.Contains(',') == false)
  25.                 {
  26.                     // 该参数列表不符合规范,搜索下一个参数列表
  27.                     IsNewStringHaveParameterList(ref startLeftParenthesis, ref indexOfLeftParenthesis, ref indexOfRightParenthesis,
  28.                             ref isStringHaveParameterList);
  29.                 }
  30.                 #endregion

  31.                 #region 如果参数列表有",",检查2个参数
  32.                 else
  33.                 {
  34.                     // 截取参数列表第一个参数
  35.                     string s1 = brackets.Substring(1, brackets.IndexOf(',') - 1);
  36.                     // 截取参数列表第二个参数
  37.                     string s2 = brackets.Substring(brackets.IndexOf(',') + 1, brackets.IndexOf(']') - brackets.IndexOf(',') - 1);

  38.                     // isN1AInt表示第一个参数是否为数字
  39.                     bool isN1AInt = int.TryParse(s1, out n1);
  40.                     // isN2AInt表示第二个参数是否为数字
  41.                     bool isN2AInt = int.TryParse(s2, out n2);

  42.                     // 如果参数列表包含的不是数字
  43.                     if (isN1AInt == false || isN2AInt == false)
  44.                     {
  45.                         // 该参数列表不符合规范,搜索下一个参数列表
  46.                         IsNewStringHaveParameterList(ref startLeftParenthesis, ref indexOfLeftParenthesis, ref indexOfRightParenthesis,
  47.                             ref isStringHaveParameterList);
  48.                     }
  49.                     // 如果参数列表格式完全正确
  50.                     else
  51.                     {
  52.                         // 返回索引
  53.                         return s.IndexOf(brackets);
  54.                     }
  55.                 }
  56.                 #endregion
  57.             }
  58.             #endregion

  59.             // 如果s不包含格式正确的参数列表
  60.             return -1;
  61.         }

  62.         private static void IsNewStringHaveParameterList(ref string startLeftParenthesis,
  63.             ref int indexOfLeftParenthesis, ref int indexOfRightParenthesis, ref bool isStringHaveParameterList)
  64.         {
  65.             // 这个参数列表格式不正确,去掉当前的'[',检查这段字符串
  66.             string stringWithOutOldLeftParenthesis = startLeftParenthesis.Substring(1);

  67.             // 检查stringWithOutOldLeftParenthesis是否包含参数列表
  68.             indexOfLeftParenthesis = stringWithOutOldLeftParenthesis.IndexOf('[');
  69.             if (indexOfLeftParenthesis != -1)
  70.             {
  71.                 // 更新startLeftParenthesis,以便下次截取
  72.                 startLeftParenthesis = stringWithOutOldLeftParenthesis.Substring(indexOfLeftParenthesis);

  73.                 indexOfRightParenthesis = startLeftParenthesis.IndexOf(']');
  74.                 isStringHaveParameterList = indexOfRightParenthesis != -1;
  75.             }
  76.             else
  77.             {
  78.                 isStringHaveParameterList = false;
  79.             }
  80.         }
复制代码

感谢大家的回复,这是我的解决方法,给大家作讨论。

作者: 亚伦    时间: 2014-5-12 21:49
忘了上图,代码和注释写得不是太好,建议设断点逐步观察,这样比较容易理解。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2