我试图弄清楚用什么最好的方法来解析传递给我的单词短语,并根据这些短语构建不同的分组。
示例XML:
<root>
<keyword value=""My First Phrase""/>
<keyword value=""My First Phrase Again""/>
<keyword value=""My First Phrase Again and Again""/>
</root>
所以我将从xml中提取出来:
My First Phrase
My First Phrase Again
My First Phrase Again and Again
然后我想从原始版本中构建这些新短语:
My First Phrase
My First
First Phrase
My
First
Phrase
My First Phrase Again
My First Phrase
First Phrase Again
My First
First Phrase
Phrase Again
My
First
Phrase
Again
这可以让我打破这些短语并从这些词中构建一种排名。我已经构建了一些列表并对它们进行了迭代,但它并不像我期望的那样工作。
所以对于排名我的意思是:
My First Phrase Again Rank: 1 (Exact Match)
My First Phrase Rank: 2
First Phrase Again Rank: 2
My First Rank: 3
First Phrase Rank: 3
Phrase Again Rank: 3
My Rank: 4
First Rank: 4
Phrase Rank: 4
Again Rank: 4
不确定解析此数据的最佳方法是什么。
谢谢,
取值
答案 0 :(得分:1)
听起来你正在考虑开发grammar。您的排名看起来与parse tree中的令牌深度相同。您的终端符号可以是任何单词,您的起始符号将是root
元素中列出的句子。
例如:
S -> X Y
X -> M F
Y -> P A
M -> "My"
F -> "First"
P -> "Phrase"
A -> "Again"
在这种情况下,“My First Phrase Again”的深度在解析树中为0,“My First”和“Phrase Again”的深度为1,深度为“My”,“First” “,”短语“和”再次“将是2。
我会开始寻找语法解析器。由于它们用于编写编译器,因此有很多这些可用。或者你可以尝试自己编写。无上下文语法实现起来相当简单;你真正需要的只是一个堆栈,一种解释和操作你的语法规则的方法。关于这方面有很多文献,因为它是一个经过深入研究的计算机科学领域。
答案 1 :(得分:1)
你需要一个后缀数组,而不是按字符分隔,用“”标记分隔。 http://en.wikipedia.org/wiki/Suffix_array
Programming Pearls中有一个很好的描述。
答案 2 :(得分:0)
如果我理解你对'等级'的定义,你可以用这样的东西来解决它:
public class PhraseRanking : IEnumerable<KeyValuePair<string, int>>
{
private readonly Dictionary<string, int> _ranking;
public PhraseRanking()
{
_ranking = new Dictionary<string, int>();
}
public PhraseRanking(string phrase)
: this()
{
var words = phrase.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var sb = new StringBuilder(phrase.Length);
for(int i = words.Length; i > 0; --i)
{
int rank = words.Length - i + 1;
int lastFirstWordIndex = words.Length - i;
for(int j = 0; j <= lastFirstWordIndex; ++j)
{
sb.Clear();
int lastWordIndex = j + i - 1;
for(int k = j; k <= lastWordIndex; ++k)
{
sb.Append(words[k]);
if(k != lastWordIndex) sb.Append(' ');
}
_ranking[sb.ToString()] = rank;
}
}
}
public int this[string phrase]
{
get { return _ranking[phrase]; }
}
public int Count
{
get { return _ranking.Count; }
}
public IEnumerator<KeyValuePair<string, int>> GetEnumerator()
{
return _ranking.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _ranking.GetEnumerator();
}
}
用法:
var ranking = new PhraseRanking("My First Phrase Again");
var sb = new StringBuilder();
foreach(var rank in ranking)
{
sb.AppendLine(rank.Value.ToString() + ": " + rank.Key);
}
MessageBox.Show(sb.ToString());
输出:
1: My First Phrase Again
2: My First Phrase
2: First Phrase Again
3: My First
3: First Phrase
3: Phrase Again
4: My
4: First
4: Phrase
4: Again