2014-11-14 32 views
-6

我正在寻找在C#中的格式的搜索字符串由用户输入的解决方案,之前调用SQL查询C#全文搜索字符串格式:字符串中删除所有相邻的重复,并附加“和”“或”

全文索引的表启用后,查询看起来像以下

select [title] from publications where contains([title], @searchString) 

主要问题:

1) add 'OR' by default between two words (ex C and C-1 below) 
1) remove adjacent duplicate from search string<br>(ex a,b,b-1, e below) 
2) remove 'AND' 'OR' at the end of the string (ex d below) 

例子:
输入=>输出

a) "oyster and oyster or fish and clean water" => "oyster or fish and clean OR water"<br> 
b) "oyster and and fish and clean water" => "oyster and fish and clean OR water"<br> 
b-1) "oyster oyster fish fish clean and water"=> "oyster or fish or clean and water" 
c) "oyster fish" => "oyster or fish"<br> 
c-1) "oyster fish clean water" => "oyster or fish or clean or water" 
d) "oyster and" => "oyster"<br> 
e) "oyster and oyster" => "oyster"<br> 

当前代码(在a,b和b-1的情况下失败;适用于C-1,d,E)

string Format(string str) 
    { 
     List<string> searchKeywords = new List<string> { "and", "or" }; 
     //convert to lower case 
     str = str.Replace(",", " ").ToLower(); 

     Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None); 
     //remove extra whitespace with space 
     str = regex.Replace(str, @" "); 

     //split string 
     string[] strArray = str.Split(' '); 

     List<string> outputArray = new List<string>(); 
     string output = ""; 
     string prevStr = ""; 
     string currStr = ""; 
     bool keywordFlag = false; 
     bool duplicateFlag = false; 

     //remove adjacent keyword or same words 
     foreach (var item in strArray) 
     { 
      currStr = item.Trim(); 
      keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr); 
      duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr); 
      if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag) 
      { 
       outputArray.Add(currStr); 
       prevStr = currStr; 
      } 
     } 

     if (outputArray.Count() == 2 && searchKeywords.Contains(outputArray[1])) 
     { 
      outputArray.Remove(outputArray[1]); 
     } 

     output = string.Join(" ", outputArray); 
     if (output.Contains(" ") && !output.Contains("and") && !output.Contains("or")) 
     { 
      return string.Join(" or ", output.Split(' ').Select(I => I.Trim())); 
     } 
     return output; 
    } 


![电流输出] [1]

牡蛎和鱼和清洁的水
牡蛎和鱼和清洁的水
牡蛎鱼干净的水
牡蛎,鱼或清洁或水
牡蛎或鱼
牡蛎
牡蛎

+3

您尝试了什么,以及您尝试的解决方案遇到什么问题?只需发布需求清单并不是一个合适的问题。 – Servy 2014-11-14 17:15:12

+0

这只是一个程序的描述,而不是一个问题。如果您未显示您迄今尝试的内容,请详细说明问题的具体内容以及您想要回答的问题,否则我们无法确定您遇到的问题。没有这些,这听起来像是你要求我们为你做。 – tnw 2014-11-14 17:21:50

+0

对不起,这是第一次发布在stackoverflow上,发布我的代码和输出。 – BeingDev 2014-11-14 17:37:15

回答

-1

既然你还没有表现出到目前为止我假设你还没有开始研究解决方案,你做了什么,所以这里是一个高层次的算法:

在这种情况下,使用String.Split(' ')来按每个空格拆分searchstring

使用所产生的字符串数组上foreach回路,并使用字符串连接来完成,如果已经用了一个词,这不是orand之前,不要将它添加到结果字符串。 如果前面的单词是orand并且当前的单词也是,请不要将其添加到结果字符串中。 如果上一个单词不是orand,而当前单词不是,则将or添加到结果字符串中。

编辑:既然代码已经公布,我可以看到什么是错的

此条件:

if (output.Contains(" ") && !output.Contains("and") && !output.Contains("or")) 
    { 
     return string.Join(" or ", output.Split(' ').Select(I => I.Trim())); 
    } 

如果输出不包含andor任何实例只获取调用

做检查,看看您的foreach循环中添加or需求,并摆脱那个条件

e。G:

  foreach (var item in strArray) 
      { 
       currStr = item.Trim(); 
       keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr); 
       duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr); 
       if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag) 
       { 
        if (!searchKeywords.Contains(prevStr) && !searchKeywords.Contains(currStr) && prevStr != "") 
        { 
         outputArray.Add("or"); 
        } 
        outputArray.Add(currStr); 
        prevStr = currStr; 
       } 
      } 

而且,当你检查,看看是否有只有2个数组中的令牌,你只是占如果他们把orand一个字后,如果他们把会发生什么or Oyster作为输入字符串?结果字符串也只是or

你需要考虑的是:

  if (outputArray.Count() == 2) 
      { 
       if(searchKeywords.Contains(outputArray[0])) 
        outputArray.Remove(outputArray[0]); 
       else if(searchKeywords.Contains(outputArray[1])) 
        outputArray.Remove(outputArray[1]); 
      } 
+0

发布代码 – BeingDev 2014-11-14 17:38:53

+0

感谢您的建议,它有帮助。
用于计数= 2
如果(outputArray.Count()== 2){ 如果 (searchKeywords.Contains(outputArray [0])) outputArray.Remove(outputArray [0]);其他 outputArray.Remove(outputArray [1]); } – BeingDev 2014-11-14 18:22:57

+0

更新你的'foreach'循环到上面和'outputArray.Count()== 2'的条件并删除你的最后一个条件,它应该工作。我运行它与提供的示例输入并得到预期的结果 – Saggio 2014-11-14 18:24:54

0

不知道这是否正确的答案,非常感谢你@saggio,寻求建议。

private string FormatSearchString(string str) 
    { 
     List<string> searchKeywords = new List<string> { "and", "or" }; 
     //convert to lower case 
     str = str.Replace(",", " ").ToLower(); 

     Regex regex = new Regex(@"[ ]{2,}", RegexOptions.None); 
     //remove extra whitespace with space 
     str = regex.Replace(str, @" "); 

     //split string 
     string[] strArray = str.Split(' '); 

     List<string> outputArray = new List<string>(); 
     string output = ""; 
     string prevStr = ""; 
     string currStr = ""; 
     bool keywordFlag = false; 
     bool duplicateFlag = false; 

     //remove adjacent keyword or same words 
     foreach (var item in strArray) 
     { 
      currStr = item.Trim(); 
      keywordFlag = searchKeywords.Contains(prevStr) && searchKeywords.Contains(currStr); 
      duplicateFlag = outputArray.Contains(currStr) && !searchKeywords.Contains(currStr); 
      if (!currStr.Equals(prevStr) && !keywordFlag && !duplicateFlag) 
      { 
       if (!searchKeywords.Contains(prevStr) && !searchKeywords.Contains(currStr) && prevStr != "") 
       { 
        outputArray.Add("or"); 
       } 
       outputArray.Add(currStr); 
       prevStr = currStr; 
      } 
     } 

     if (outputArray.Count() == 2) 
     { 
      if (searchKeywords.Contains(outputArray[0])) 
       outputArray.Remove(outputArray[0]); 
      else 
       outputArray.Remove(outputArray[1]); 
     } 

     output = string.Join(" ", outputArray); 

     return output; 
    } 
相关问题