代码之家  ›  专栏  ›  技术社区  ›  Liggi

如何从一个字符串中解析两个主题?

  •  0
  • Liggi  · 技术社区  · 14 年前

    这很难解释。我现在正在进行一个文本冒险,我正在分析一个玩家的输入。

    当一个玩家输入时,有两个可能的主题(我们称它们为Subject1和Subject2)。例如,在下面的“用棍子打门”中,主题1是“门”,主题2是“棍子”。

    在这种情况下,门和斗杆都属于“项目”类型。也可以有“字符”类型的主题。

    问题是,如果我分析项目,然后分析字符,项目分析会发现项目是Subject1,即使它实际上是第二个主题。我使用的代码如下:

    public static void ParseForSubjects(string Input, Player CurrentPlayer, ref object Subject1, ref object Subject2)
    {
        // This method doesn't really work properly, as it looks up Inventory items, Environment items and then Characters in order
        // when it may well be that a character is subject1 and an item is subject2, but they will be reversed because of the parsing order
        Input = Input.ToLower();
    
        // Parse items in Player inventory
        foreach (Item InventoryItem in CurrentPlayer.Inventory)
        {
            if (Input.Contains(InventoryItem.Name.ToLower()))
            {
                if (Subject1 == null)
                {
                    Subject1 = InventoryItem;
                }
                else
                {
                    Subject2 = InventoryItem;
                }
            }
        }
    
        // Parse items in environment
        foreach (Item EnvironmentalItem in CurrentPlayer.CurrentArea.Items)
        {
            if (Input.Contains(EnvironmentalItem.Name.ToLower()))
            {
                if (Subject1 == null)
                {
                    Subject1 = EnvironmentalItem;
                }
                else
                {
                    Subject2 = EnvironmentalItem;
                }
            }
        }
    
        // Parse present characters
        foreach (Character PresentCharacter in CurrentPlayer.CurrentArea.Characters)
        {
            if (Input.Contains(PresentCharacter.Name.ToLower()))
            {
                if (Subject1 == null)
                {
                    Subject1 = PresentCharacter;
                }
                else
                {
                    Subject2 = PresentCharacter;
                }
            }
        }
    }
    

    我确信这是否足够清楚。基本上,无论类型如何,我都需要subject1是输入字符串中的第一个主题,subject2是输入字符串中的第二个主题。

    请随意提问,这可能不是100%清楚。

    4 回复  |  直到 14 年前
        1
  •  2
  •   Nathan Wheeler    14 年前

    检查一下就行了 Input.IndexOf(Subject1.Name.ToLower()) < Input.IndexOf(Subject2.Name.ToLower()) 如果是错误的,那么就切换它们。

        2
  •  1
  •   Jim Mischel    14 年前

    我建议你把逻辑颠倒过来。与其检查每个库存项目以查看是否在字符串中提到它,不如分析该字符串并检查该项目的库存。例如:

    string[] parsedInput = Input.Split([' ']);
    

    现在您有了一个包含用户输入的数组,一个字接一个字。如果你总是知道subject1是第二个词,subject2是第四个词,那么:

    string subject1 = parsedInput[1];
    // check to see if subject1 is in the Inventory or the Environment collections
    

    用同样的方法 subject2 (即 parsedInput[3] )

    如果不能保证主题在数组中的位置,那么必须对数组进行迭代,以确定哪些项目是主题。关键是使用用户的输入来检查库存/环境/字符集合,而不是反过来。与其说:

    for each item in inventory/environment/characters
      did user's input mention this?
    

    而是说:

    for each item that the user mentioned
      is it in the inventory/environment/characters collections?
    
        3
  •  0
  •   Jeremy Goodell    14 年前

    你能做一些非常简单的事情吗,比如保存你找到的每个主题的起始位置,然后在你的函数结束时,使用保存的位置来确定哪个主题是第一个的?

        4
  •  0
  •   Eight-Bit Guru    14 年前

    如果我理解正确的话,实际上您所说的是,如果在库存集合中首先找到“Stick”,那么它将成为Subject1,即使它实际上是输入行中的Subject2。如果是这样,为什么不改变 Subject 变量到数组中,然后根据输入中名词的位置填充该数组?

    因此, Subject[] 将填充为: Subject[1]="door" Subject[2]="stick" 。然后迭代数组,按升序处理主题。

    这需要更多的支持代码来确定您当前正在分析的输入中的“n”名词,但是如果您重新构造解析循环,以便分析输入而不是清单,那么这就变得很简单了。

    这篇文章也有助于完善这方面的思考过程: Natural Language Processing