100分征一搜索算法

hnicyipb 2007-12-26 05:21:52
输入参数
搜索字符串 匹配字数

现在有一数据表 id,content 两列

比如:
客户输入

搜索字符串:"Microsoft Visual Web Developer 2008"
匹配字数 :3

要求输出结果为:
content 列中包含“Microsoft Visual Web ”,“Visual Web Developer ”,“Web Developer 2008”,“Microsoft Visual Web Developer ”,“Visual Web Developer 2008”,“Microsoft Visual Web Developer 2008”
这几个字符串的记录
...全文
327 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
guoqishao 2008-01-07
  • 打赏
  • 举报
回复
1,构造一个合并的数组a,假设要处理的为“12345”,则生成“1234512345”
2,从左到右扫描一次数组,截取子数组长度为3,4,5,问题解决
hnicyipb 2008-01-05
  • 打赏
  • 举报
回复
呵呵...前两天出差了,没及时结...不好意思
hnicyipb 2008-01-05
  • 打赏
  • 举报
回复
呵...谢谢各位大大...搞定了.谢谢
haiwangstar 2007-12-27
  • 打赏
  • 举报
回复
http://msdn.microsoft.com/msdnmag/issues/07/02/SQLRegex/default.aspx?loc=zh
haiwangstar 2007-12-27
  • 打赏
  • 举报
回复
个人认为最好的方法是在SQL 存储过程程序集中实现,读出来后再处理的方法,必竟效率会比较低。
建议楼主参考这个。
http://blogs.msdn.com/sqlclr/archive/2005/06/29/regex.aspx
LeeeeSin 2007-12-27
  • 打赏
  • 举报
回复
先用Split切开成数组,然后每3到数组成员个数,组成一个string,
组成的String分别为:“Microsoft Visual Web ”,“Visual Web Developer ”,“Web Developer 2008”.

然后再查数据库匹配项
,,,
jupiter911 2007-12-27
  • 打赏
  • 举报
回复
代码来了~

private ArrayList Split(object[] obj , int N)
{
ArrayList Outer= new ArrayList();
int length = obj.Length + 1;
//设定取值范围N至obj.Length
for(int i = N ; i < length ; i ++)
{
//从第j个元素开始取值
for(int j = 0 ; j < length - i ; j ++)
{
ArrayList list = new ArrayList();
//取数量为i的元素
for(int k = 0 ; k < i ; k ++)
{
list.Add(obj[k+j]);
}
Outer.Add(list);
}
}
return Outer;
}
changjiangzhibin 2007-12-27
  • 打赏
  • 举报
回复
用split分开后,按需求遍历或加减处理就可以了
jschl1981 2007-12-27
  • 打赏
  • 举报
回复
我粗略想了一个算法如下:
0。 给目标字符和被查找的字符串split
1。 给目标字符串的每个单词 安顺序 编号, 比如:
Microsoft : 0
Visual : 1
Web : 2
Developer : 3
2008 : 4
2。 在被查询的字符串标记每个单词编号。如果该单词在目标单词中,则用目标单词的号码,如果不存在,则标记为最小指。
比如,Java Web Developer Visual Web Developer 的标记方法为:
Java : -2147483648
Web : 2
Developer : 3
Visual : 1
Web : 2
Developer : 3
3。 遍历被查询字符串,如果 value[i] - value[i-1] = 1 连续出现 n -1次,则代表找到了目标字符串 。 搂主设定n=3。
比如在上面的例子里,1 2 3 连续出现,所以找到了目标字符串。

算法最复杂的地方是二步,复杂度为 N * M ,N 是目标字符串的单词的个数,M是被查询的字符串中单词个数。似乎复杂度与查询长度无关????

想听听大家关于这个算法复杂度的意见。下面是可以运行的code。

string targetString = "Microsoft Visual Web Developer 2008";
int depth = 3;
string content = "Java Web Developer Visual Web Developer ";

char[] sperator = new char[1] { ' ' };
string[] targetStringElements = targetString.Split(sperator, StringSplitOptions.RemoveEmptyEntries);
string[] contentElements = content.Split(sperator, StringSplitOptions.RemoveEmptyEntries);

int[] indicator = new int[contentElements.Length];
for (int i = 0; i < indicator.Length; i++)
indicator[i] = int.MinValue;


for (int i = 0; i < targetStringElements.Length; i++)
{
for (int j = 0; j < contentElements.Length; j++)
{
if (targetStringElements[i] == contentElements[j])
indicator[j] = i;
}
}
for (int i = 0; i < indicator.Length; i ++)
System.Console.WriteLine("{0} : {1}", contentElements[i], indicator[i]);
for (int i = 0; i < indicator.Length - depth + 1; i++)
{
int j = depth;
if (indicator[i] != int.MinValue)
{
while ((j > 1) && (indicator[i + j - 1] - indicator[i + j - 2] == 1))
j--;
if (j == 1)
{
System.Console.WriteLine("The sub string begins at position {0}", i);
}
}
}
shrinerain 2007-12-27
  • 打赏
  • 举报
回复
如果你的要求很高, 比如搜索引擎级别, 考虑hash.

那么建议你将字符串按照单词个数分段做hash, 比如, 假如用户常用的匹配个数是3个单词.

那么就将字符串按每三个单词拆分,分别hash.

shrinerain 2007-12-27
  • 打赏
  • 举报
回复
你的问题其实和"寻找共同子序列" 没有什么区别, 你将你的"单词"看成"字母"就可以了, 就是一个普普通通的"寻找相同字符数大于3的共同子序列"问题.

标准答案, 你用KMP算法.

KMP觉得麻烦,用动态规划.

如果你什么算法都不会, 就两个for循环, 也行.
chengzhe 2007-12-27
  • 打赏
  • 举报
回复
呵呵
jupiter911 2007-12-27
  • 打赏
  • 举报
回复
赶紧给分哪
haiwangstar 2007-12-26
  • 打赏
  • 举报
回复
用.NET做SQL SERVER的程序集存储过程,在程序集中使用正则表达式,然后在SQL语句中调用你的程序集。即可。
VirtualDesktop 2007-12-26
  • 打赏
  • 举报
回复
用正则表达式 ....
Soloboy1020 2007-12-26
  • 打赏
  • 举报
回复
用的SQL SERVER的数据库

现在只想在C#中实现可能方便点。最后还是写到存储过程中
===================================================
最简单的就是关键字先split然后自己组合了生成查询条件了
不过效果估计不会很好,比如汉字 ,处理起来就很麻烦了

Efcndi 2007-12-26
  • 打赏
  • 举报
回复
"MicrosoftVisualWebDeveloper2008"这种不算的话,
dest[j].Contains(sub[i])这句要改一下,
写一个函数把dest[j] split再一个个比较。
Efcndi 2007-12-26
  • 打赏
  • 举报
回复
这个表述还不够清晰。
如果源字符串存在相同的子串怎么办?
如输入“C# C# C#”该怎么处理,应该说明一下。

假设源字符串没有相同的子串:

1、为每个目标串建立一个计数器,假设有n个目标串,则定义int[n] counter;
counter[i]记录目标串i与源字符串有几个子字符串匹配。

2、取出源字符串的各个子串

3、将源字符串的每个子串和所有的目标串进行匹配。
如果发现第i个目标串和该子串匹配,则++counter[i];

4、输出counter[i]不小于要求匹配字数的目标串。

实现:


1、int[DestCount] counter;
string[DestCount] dest;

2、String.Split();

3、for(int i=0; i<subCount; ++i)
{
for(int j=0; j<DestCount; ++j)
{
if(dest[j].Contains(sub[i]))
{
++counter[j];
}
}
}

int matchCount; //user input
4、for(int i=0; i<DestCount; ++i)
{
if(counter[i] >= matchCount)
{
output dest[i];
}
}

hnicyipb 2007-12-26
  • 打赏
  • 举报
回复
Soloboy1020
NewPlayer
等 级:
发表于:2007-12-26 17:56:598楼 得分:0
你用的什么数据库啊,做个全文搜索好了

=======================================================

用的SQL SERVER的数据库

现在只想在C#中实现可能方便点。最后还是写到存储过程中
hnicyipb 2007-12-26
  • 打赏
  • 举报
回复
vwxyzh
yzh - Invalid method body.
等 级:
发表于:2007-12-26 17:45:066楼 得分:0
“MicrosoftVisualWebDeveloper2008”(没空格的)算不算?

=====================================================
这个不算。
加载更多回复(9)

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧