算法擂台——根据文本产生字典

threenewbee 2011-05-07 09:11:46
加精
注意,测试数据已经上传,位于:http://download.csdn.net/source/3257888
上一个问题是不是有点难,先来一个简单的问题热身下。

考虑这样一个问题,给定一段输入文本,从中提取所有的单词,并且输出,要求输出的单词经过排序,不区分大小写,而且不重复和遗漏。

比如:"Hello World! Hello everyone, my name is caozhy!"
输出:
caozhy
everyone
hello
is
my
name
world

下面给一个我的实现:
    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().ToLower() + 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().ToUpper().ToCharArray();
for (int i = 0; i < arr.GetLength(0); i++)
{
if (arr[i] >= 65 && arr[i] <= 90)
{
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();
}
}
...全文
2477 114 打赏 收藏 转发到动态 举报
写回复
用AI写文章
114 条回复
切换为时间正序
请发表友善的回复…
发表回复
vcvj 2011-05-25
  • 打赏
  • 举报
回复
gz gz gz
hxy513282424 2011-05-16
  • 打赏
  • 举报
回复
这种问题我一般用c++使用STL的map,直接put,然后使用iterator输出。
O(nlogn)
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 ojlovecd 的回复:]

I'm
aren't
这种算一个词还是两个词?
[/Quote]

到底应该算几个?
种草德鲁伊 2011-05-16
  • 打赏
  • 举报
回复
这个实现起来还比较简单...
  • 打赏
  • 举报
回复
最好能给个区分变异词,同义词的算法
wei303578743 2011-05-14
  • 打赏
  • 举报
回复
我不懂算法,我看各楼的帖子,我特别好奇,也没发现有人问我这么小白的问题,可是我不知道怎么回事,所以还是想问一下?
楼上各位的代码是啥意思,为什么有中文啊,是易语言吗?
wei303578743 2011-05-14
  • 打赏
  • 举报
回复
好东西呀,找了好久,用一下!
lyy_0814 2011-05-13
  • 打赏
  • 举报
回复
我不懂算法,我看各楼的帖子,我特别好奇,也没发现有人问我这么小白的问题,可是我不知道怎么回事,所以还是想问一下?
楼上各位的代码是啥意思,为什么有中文啊,是易语言吗?
香椿炒鸡蛋 2011-05-10
  • 打赏
  • 举报
回复
研究下书本的单词 首字母服从什么分布? 不知道是不是正态分布。。

根据具体的分布情况自己重新写一个排序算法出来,系统自带的都是通用型的 要么快排等。。

根据分布 改写排序算法 这个是我的建议
llwz0565 2011-05-10
  • 打赏
  • 举报
回复
手上恰好没有很长的英文 电子版的书。。
threenewbee 2011-05-09
  • 打赏
  • 举报
回复
[Quote=引用 81 楼 baihacker 的回复:]
C# code

//重新放在ArrayList里了
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

name……
[/Quote]
这个算法应该和我的一样,但是效率要高一些。
qw_zr 2011-05-09
  • 打赏
  • 举报
回复
经测试,楼主(caozhy )和3楼(LCL_data)的算法,楼主更快。
Windows XP3 32位笔记本,不考虑界面显示,
caozhy 耗时为 165±10 毫秒
LCL_data 耗时为 220±10 毫秒

27楼的测试结果有一定问题,因为 caozhy 算法中使用了 tr.ReadLine() ,为公平起见,这句话应更改为 tr.ReadToEnd(),并去掉 while(true) 。
baihacker 2011-05-09
  • 打赏
  • 举报
回复

//重新放在ArrayList里了
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace ConsoleApplication1
{
class Program
{
public class Node
{
public Node[] cld;
public bool have;
public Node()
{
cld = new Node[26];
for (int i = 0; i < 26; ++i)
cld[i] = null;
have = false;
}
public Node forward(int x)
{
if (cld[x] != null) return cld[x];
return cld[x] = new Node();
}
}

public void dfs(Node now, string build, ArrayList ret)
{
if (now.have == true) ret.Add(build);
for (int i = 0; i < 26; ++i) if (now.cld[i] != null)
{
dfs(now.cld[i], string.Copy(build) + (char)(i+'a'), ret);
}
}

public void parse()
{
StreamReader objReader = new StreamReader("D:\\source.txt");
string s = objReader.ReadToEnd();
objReader.Close();
Node root = new Node();
Node curr = root;
for (int i = 0; i < s.Length; ++i)
{
int who = s[i];
if (who >= 'A' && who <= 'Z') who |= 32;
if (who < 'a' || who > 'z')
{
if (curr != root)
{
curr.have = true;
curr = root;
}
}
else
{
curr = curr.forward(who-'a');
}
}
ArrayList ans = new ArrayList();
dfs(root, "", ans);
System.Console.Write("{0} elements have been found!\n", ans.Count);
//foreach(var x in ans) System.Console.WriteLine(x);
}

static void Main(string[] args)
{
long l = DateTime.Now.Ticks;
(new Program()).parse();
TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - l);
MessageBox.Show(ts.ToString());

}
}
}
csproj 2011-05-09
  • 打赏
  • 举报
回复
5006个应该是对的。
还有5000个字符相连用StringBuilder速度要快很多
baihacker 2011-05-09
  • 打赏
  • 举报
回复

//不大熟悉C#参考了一些楼上的代码,好不容易拼出来的程序。
//计时不包括控制台的输出,否则把注释掉的打开就行
//to 11楼我的结果和lcl_data的结果,在你发出来的部分是一样的
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace ConsoleApplication1
{
class Program
{
public class Node
{
public Node[] cld;
public bool have;
public Node()
{
cld = new Node[26];
for (int i = 0; i < 26; ++i)
cld[i] = null;
have = false;
}
public Node forward(int x)
{
if (cld[x] != null) return cld[x];
return cld[x] = new Node();
}
}

public void dfs(Node now, string build)
{
if (now.have == true) System.Console.WriteLine(build);
for (int i = 0; i < 26; ++i) if (now.cld[i] != null)
{
dfs(now.cld[i], string.Copy(build) + (char)(i+'a'));
}
}

public void parse()
{
StreamReader objReader = new StreamReader("D:\\source.txt");
string s = objReader.ReadToEnd();
objReader.Close();
Node root = new Node();
Node curr = root;
for (int i = 0; i < s.Length; ++i)
{
int who = s[i];
if (who >= 'A' && who <= 'Z') who |= 32;
if (who < 'a' || who > 'z')
{
if (curr != root)
{
curr.have = true;
curr = root;
}
}
else
{
curr = curr.forward(who-'a');
}
}
//dfs(root, "");
}

static void Main(string[] args)
{
long l = DateTime.Now.Ticks;
(new Program()).parse();
TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - l);
MessageBox.Show(ts.ToString());

}
}
}
yhxyhxyhx 2011-05-09
  • 打赏
  • 举报
回复
trie tree
blacksapper 2011-05-09
  • 打赏
  • 举报
回复
排序,输出,
输出的时候检查当前词汇.如果是老单词就不输出.
batmanlf 2011-05-09
  • 打赏
  • 举报
回复
版主推荐区进来的
不会用c#
我用python写一个行不行
import string

def stat(strin):
maketrans = strin.maketrans(string.punctuation, ' '*len(string.punctuation))
strin = strin.translate(maketrans)
strin = strin.strip()
word = strin.strip()
word.sort()
for i in word:
print(i)
batmanlf 2011-05-09
  • 打赏
  • 举报
回复
版主推荐区进来的
不会用c#
我用python写一个行不行
import string

def stat(strin):
maketrans = strin.maketrans(string.punctuation, ' '*len(string.punctuation))
strin = strin.translate(maketrans)
strin = strin.strip()
word = strin.strip()
word.sort()
for i in word:
print(i)
  • 打赏
  • 举报
回复
楼主给出的单词好像总是多一些。
public static IEnumerable<string> ParseString1(TextReader tr)
{
return ParseString2(tr).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Distinct().OrderBy(i => i);
}

public static string ParseString2(TextReader tr)
{
var s = tr.ReadToEnd().ToCharArray();
for (var x = 0; x < s.Length; x++)
if (s[x] >= 65 && s[x] <= 90)
s[x] += (char)32;
else if (s[x] < 97 || s[x] > 122)
s[x] = ' ';
return new string(s);
}

加载更多回复(47)

110,545

社区成员

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

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

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