C# 将短语解析为不同的词对

C# 将短语解析为不同的词对,c#,c#-3.0,c#-4.0,C#,C# 3.0,C# 4.0,我正试图找出最好的方法是用什么来解析传递给我的单词短语,并根据这些短语建立不同的分组 XML示例: <root> <keyword value=""My First Phrase""/> <keyword value=""My First Phrase Again""/> <keyword value=""My First Phrase Again and Again""/> </root> 然后,我想从原文中构建这

我正试图找出最好的方法是用什么来解析传递给我的单词短语,并根据这些短语建立不同的分组

XML示例:

<root>
   <keyword value=""My First Phrase""/>
   <keyword value=""My First Phrase Again""/>
   <keyword value=""My First Phrase Again and Again""/>
</root>
然后,我想从原文中构建这些新短语:

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
不确定解析此数据的最佳方法是什么

谢谢


听起来你在考虑开发一个新的应用程序。你的排名看起来就像他们的代币的深度一样。终端符号可以是任何单词,起始符号可以是
根元素中列出的句子

例如:

S -> X Y
X -> M F
Y -> P A
M -> "My"
F -> "First"
P -> "Phrase"
A -> "Again"
在本例中,解析树中“我的第一个短语再次”的深度为0,“我的第一个”和“短语再次”的深度为1,“我的”、“第一个”、“短语”和“再次”的深度为2


我会开始四处寻找语法分析器。因为它们用于编写编译器,所以有很多可用的方法。或者你也可以试着自己写。上下文无关语法实现起来相当简单;您真正需要的只是一个堆栈和一种解释和操作语法规则的方法。关于这一点有很多文献,因为它是计算机科学的一个研究很好的领域。

如果我正确理解了你对“等级”的定义,你可以用以下方法来解决它:

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();
    }
}
输出:

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

您需要一个后缀数组,但不是按字符分隔,而是用“”标记分隔


这一点在本书中有很好的描述

你能提供排名的英文描述吗?我有点不清楚,如果“我的第一个”是第三名,为什么“短语再次”会是第四名。对不起,杰克,那是个错误,应该是第三名,就像其他人一样。我编辑它来纠正错误
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