算法擂台——比较字符串

threenewbee 2011-05-07 06:14:26
加精
看看C#版各位猛人算法基本功如何,出一个简单但是有趣的题目:

题目:
如何在给定的单词表中寻找两个相似的单词。
目标:
按照相似度排序,越符合直观相似度的获胜。

比如:
和 abcdefg 匹配: acdefg 要优于 abcdfff
和 abcdefg 匹配: abcdzzz 要优于 gfacbde
和 abcdefg 匹配: abefgcd 要优于 gfacbde
和 abcdefg 匹配: adcdefg 要优于 accdefg
...

贴一个字典给大家:

http://download.csdn.net/source/3257888


贴一个我的程序:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static List<string> Dict;

static void Main(string[] args)
{
StreamReader objReader = new StreamReader("c:\\source.txt");
Dict = DictGen.ParseString(objReader).ToList();
string s1 = "";
while (s1 == "")
{
Console.WriteLine("Please input a word:");
s1 = Console.ReadLine();
}
CompareString cs = new CompareString();
var match = Dict.AsParallel().Select(x => new { key = cs.Compare(x, s1), value = x })
.OrderBy(x => x.key)
.ThenBy(x => x.value)
.Where(x => x.key <= (s1.Length / 2 == 0 ? 1 : s1.Length / 2));
match.ToList().ForEach(x => Console.WriteLine(x.value + "\t\t" + x.key.ToString()));
}
}

class CompareString
{
public int Compare(string S, string D)
{
if (string.IsNullOrEmpty(S) || string.IsNullOrEmpty(D))
throw new Exception("String should not be empty.");
int[,] array = new int[S.Length + 1, D.Length + 1];
for (int i = 0; i <= S.Length; i++)
array[i, 0] = i;
for (int i = 1; i <= D.Length; i++)
array[0, i] = i;
for (int i = 1; i <= S.Length; i++)
{
for (int j = 1; j <= D.Length; j++)
{
int c = S[i - 1] == D[j - 1] ? 0 : 1;
int n1 = array[i - 1, j] + 1;
int n2 = array[i - 1, j - 1] + c;
int n3 = array[i, j - 1] + 1;
int v = n1 < n2 ? n1 : n2;
array[i, j] = v < n3 ? v : n3;
}
}
return array[S.Length, D.Length];
}
}

class DictGen
{
class Node
{
public Dictionary<char, Node> Dict { get; set; }
public Node() { Dict = new Dictionary<char, Node>(); }

public IEnumerable<string> Get()
{
foreach (var item in Dict.OrderBy(x => x.Key))
{
if (item.Key == '\0') yield return "";
foreach (var item1 in item.Value.Get())
{
yield return item.Key.ToString() + item1;
}
}
}
}

public static IEnumerable<string> ParseString(TextReader tr)
{
Node rootNode = new Node();
Node currNode = rootNode;
int state = 0;
char[] arr;
try
{
while (true)
{
arr = tr.ReadLine().ToLower().ToCharArray();
for (int i = 0; i < arr.GetLength(0); i++)
{
if (arr[i] >= 'a' && arr[i] <= 'z')
{
state = 1;
if (!currNode.Dict.ContainsKey(arr[i]))
currNode.Dict.Add(arr[i], new Node());
currNode = currNode.Dict[arr[i]];
}
else
{
if (state == 1)
{
if (!currNode.Dict.ContainsKey('\0'))
currNode.Dict.Add('\0', new Node());
state = 0;
}
currNode = rootNode;
}
}
}
}
catch
{ }
return rootNode.Get();
}
}


}


运行结果:
Please input a word:
asdf
asif 1
ad 2
add 2
adds 2
ado 2
aid 2
aide 2
aids 2
and 2
as 2
asax 2
asc 2
ascx 2
ask 2
asp 2
aspx 2
axd 2
msdn 2


Please input a word:
through
through 0
though 1
thought 2
although 3
brought 3
enough 3
throughout 3
throughthe 3
throw 3
thrown 3
throws 3
touch 3
wrought 3


Please input a word:
whateverx
whatever 1
thatevery 2
whenever 3
wherever 3
however 4
whatthe 4
whatwe 4
whether 4
whichever 4


Please input a word:
caozhy
cache 3
canonly 3
catch 3
caught 3
copy 3


Please input a word:
controllers
controllers 0
controller 1
acontroller 2
controllerto 2
icontroller 2
controllerbase 3
controllerdoes 3
controllersand 3
controllerthe 3
controlling 3
controloffers 3
controls 3
controlsas 3
ourcontrollers 3
thecontrollers 3
anicontroller 4
consoleis 4
containers 4
control 4
controllercode 4
controllername 4
controllersseem 4
controllertake 4
controllertype 4
controlseven 4
controlson 4
controlswe 4
ioccontroller 4
manycontrollers 4
thecontroller 4
yourcontrollers 4
acontrol 5
centers 5
console 5
constructors 5
container 5
continues 5
contributes 5
contributors 5
contrived 5
controllertester
controllerwhere 5
countries 5
customers 5
homecontroller 5
installers 5
ownicontroller 5
thiscontroller 5
viewcontroller 5
yourcontroller 5

Please input a word:
framewok
framework 1
aframework 2
frameworks 2
frame 3
facebook 4
fragment 4
fragments 4
mvcframework 4
namefor 4
netframework 4
sameway 4
theframework 4

Please input a word:
g
a 1
b 1
c 1
d 1
e 1
f 1
go 1
h 1
i 1
m 1
n 1
o 1
p 1
r 1
s 1
t 1
v 1
w 1
x 1
y 1
z 1
...全文
5846 127 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
127 条回复
切换为时间正序
请发表友善的回复…
发表回复
pincute 2011-05-20
  • 打赏
  • 举报
回复
这位道友给力的!
[Quote=引用 114 楼 jy02305022 的回复:]

引用 98 楼 pincute 的回复:

C# code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(str……
[/Quote]
congxiaowan 2011-05-16
  • 打赏
  • 举报
回复
只是来跟帖。。。
lmkjh 2011-05-16
  • 打赏
  • 举报
回复
看来还成。
liqi_ 2011-05-16
  • 打赏
  • 举报
回复
可能会用到模糊吧
zlcp520 2011-05-16
  • 打赏
  • 举报
回复
内容存入剪贴板
「已注销」 2011-05-16
  • 打赏
  • 举报
回复
[Quote=引用 98 楼 pincute 的回复:]

C# code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
……
[/Quote]



string s = "zs151as12a51s12";
for (int i = (int)'a'; i <= (int)'z'; i++)
s = s.Replace((char)i, ',');

int sum = 0;
foreach (var item in s.Split(','))
if (item != "")
sum += int.Parse(item);

Console.WriteLine(sum);


不要说效率,只求代码简洁
Wonderman1168 2011-05-16
  • 打赏
  • 举报
回复
初来乍到,看的不是很懂
hurongfz 2011-05-13
  • 打赏
  • 举报
回复
太像编辑距离算法了?copy来的?
bjgovcomjiachao 2011-05-13
  • 打赏
  • 举报
回复
多谢了
有C版本的吗?
我指针操作不熟悉,往大虾们给予指导
万事屋 2011-05-13
  • 打赏
  • 举报
回复
貌似 obob 的升级

[Quote=引用 73 楼 newegg2009 的回复:]

+1
引用 67 楼 litaoye 的回复:
每次弄这种字符串的模糊匹配,我都会写一遍lcs(最长公共子序列)的程序,每次用到最后又都会把lcs给删掉,因为经常需要用精确匹配。真是悲剧,只好再写一遍了。

比如abcac同bbdac的lcs是bac,另外还有一种利用dp求编辑距离的方法,也是n^2的复杂度


C# code

public static string LCS……
[/Quote]
pincute 2011-05-12
  • 打赏
  • 举报
回复
各位达人,现在有这么一个随机的字符串,只由字母和数字组成
比如"aa44aa49a44aaaa"
如何取出里面的数字 然后再求和呢? 注意连在一起的数字算做一个
上面的例子"aa44aa49a45aaaa"
最终结果是44+49+45=148
字符串的组成是完全随机的 "44aa49a49aass"..."zs151as12a51s12"..
求解答!
wesweeky 2011-05-12
  • 打赏
  • 举报
回复
字典下不下来。。
pincute 2011-05-12
  • 打赏
  • 举报
回复
[Quote=引用 84 楼 binqray 的回复:]
引用 80 楼 pincute 的回复:
各位达人,现在有这么一个随机的字符串,只由字母和数字组成
比如"aa44aa49a44aaaa"
如何取出里面的数字 然后再求和呢? 注意连在一起的数字算做一个
上面的例子"aa44aa49a45aaaa"
最终结果是44+49+45=148
字符串的组成是完全随机的 "44aa49a49aass"..."zs151as12a51s12"..
……
[/Quote]

用C/C++来做不难
现在用C#来做 有点晕
pincute 2011-05-12
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
String str = "a444a44asd343asd41a";
int num = 0;
for (int i = 0; i < str.Length; i++)
{
if (char.IsNumber(str[i]))
{
int j = 0;
String temp = null;
for (j = i; j < str.Length; j++)
{
if (char.IsNumber(str[j]) == false)
break;
temp += str[j].ToString();
}
i = j;
num += Int32.Parse(temp);
Console.Write("提取出来的数字为:");
Console.WriteLine(temp);
}
}
Console.WriteLine("和为:"+num);
Console.Read();
}
}
}

[Quote=引用 80 楼 pincute 的回复:]
各位达人,现在有这么一个随机的字符串,只由字母和数字组成
比如"aa44aa49a44aaaa"
如何取出里面的数字 然后再求和呢? 注意连在一起的数字算做一个
上面的例子"aa44aa49a45aaaa"
最终结果是44+49+45=148
字符串的组成是完全随机的 "44aa49a49aass"..."zs151as12a51s12"..
求解答!
[/Quote]
解决了,但总觉得很罗嗦..
有没有牛人来点简洁的?
pincute 2011-05-12
  • 打赏
  • 举报
回复
这位仁兄,谢了
java的pattern和macther的确很好用 很简洁
今天用C#解决了 但是看起来依然很别扭
用C#有没有更简洁的?
[Quote=引用 94 楼 hlj845629143 的回复:]
import java.util.regex.*;

public class RegexTest
{
public static void main(String[] args)
{
String str = "zs151as12a51s12";
Pattern p = Pattern.compile("[0-9]{1,}");

Matcher m = p.matcher……
[/Quote]
V-Far 2011-05-12
  • 打赏
  • 举报
回复
对这个是一点概念都没有.
貌似Beyond Compare这个软件做的比较好
天外来客-007 2011-05-12
  • 打赏
  • 举报
回复
就是字符串的相似度问题,下面讲的很好,推荐看!
http://www.cnblogs.com/liushannet/archive/2010/10/25/1860358.html
  • 打赏
  • 举报
回复
[Quote=引用 80 楼 pincute 的回复:]
各位达人,现在有这么一个随机的字符串,只由字母和数字组成
比如"aa44aa49a44aaaa"
如何取出里面的数字 然后再求和呢? 注意连在一起的数字算做一个
上面的例子"aa44aa49a45aaaa"
最终结果是44+49+45=148
字符串的组成是完全随机的 "44aa49a49aass"..."zs151as12a51s12"..
求解答!
[/Quote]

这个貌似不难。
myhope88 2011-05-12
  • 打赏
  • 举报
回复
看得真晕
牙痴 2011-05-12
  • 打赏
  • 举报
回复
import java.util.regex.*;

public class RegexTest
{
public static void main(String[] args)
{
String str = "zs151as12a51s12";
Pattern p = Pattern.compile("[0-9]{1,}");

Matcher m = p.matcher(str);

int sum = 0;

while(m.find())
{
int start = m.start();
int end = m.end();
System.out.println(start+"\t"+end);
String s = str.substring(start,end);
sum += Integer.parseInt(s);
}

System.out.println(sum);
}
}
加载更多回复(29)

111,092

社区成员

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

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

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