【问题标题】:Iterating backwards through an char array after finding a known word找到已知单词后通过 char 数组向后迭代
【发布时间】:2015-07-14 20:43:46
【问题描述】:

我有一个正在使用 C# 进行的项目。我有两个字符数组。一个是句子,一个是单词。我必须遍历句子数组,直到找到一个与变成单词数组的单词相匹配的单词通过与单词数组相同的长度找到单词?

代码:

String wordString = "(Four)";
String sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
char[] wordArray = wordString.ToCharArray();
List<String> words = sentenceString.Split(' ').ToList<string>();
//This would be the part where I iterate through sentence
foreach (string sentence in sentArray)
{
     //Here I would need to find where the string of (Four) and trim it and see if it equals the wordString. 
     if (sentence.Contains(wordString)
     {
         //At this point I would need to go back the length of wordString which happens to be four places but I'm not sure how to do this.  And for each word I go back in the sentence I need to capture that in another string array.
      }

我不知道我对此是否足够清楚,但如果我不是,请随时询问.. 提前谢谢你。这应该返回的是“乌拉圭中继器的家禽”。所以基本上用例是括号中的字母数,逻辑应该在括号中的单词之前返回相同数量的单词。

【问题讨论】:

  • 你必须只使用char数组??究竟输出应该是什么?
  • 不,这不应该是我想用的,不知道这是否是最好的方法。这个输出应该返回“乌拉圭中继器的家禽”
  • 是什么阻止你使用 sentenceString.IndexOf(wordString) ?
  • 使用 indexOf、Substring 等的组合
  • 为什么输出应该返回“乌拉圭中继器的家禽”而不是“乌拉圭中继器的家禽”?

标签: c# arrays char


【解决方案1】:

我们是你。我对这个练习没有什么疑问。 如果单词 (四) 在开头,它不应该返回吗?或返回所有字符串? 由于 四的长度等于 4 想象如果该单词作为句子中的第二个单词出现,它应该只返回第一个单词或返回 4 个单词,甚至包括(四个)单词。?

我的解决方案是最懒惰的,我刚刚看到你的问题并决定提供帮助。

  • 如果长度大于 (four) 单词之前的单词,我的解决方案假定它返回 (four) 之前的所有单词。
  • 如果单词 (four) 在开头,我的解决方案会返回空字符串。
  • 我的解决方案返回 (四) (4) 个字在 (四) 字之前的长度。

再一次,这不是我最好的方法。

我看到下面的代码:

        string wordString = "(Four)";
        string sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
        //Additionally you can add splitoption to remove the empty word on split function bellow
        //Just in case there are more space in sentence.
        string[] splitedword = sentenceString.Split(' ');
        int tempBackposition = 0;
        int finalposition = 0;
        for (int i = 0; i < splitedword.Length; i++)
        {
            if (splitedword[i].Contains(wordString))
            {
                finalposition = i;
                break;
            }
        }
        tempBackposition = finalposition - wordString.Replace("(","").Replace(")","").Length;
        string output = "";
        tempBackposition= tempBackposition<0?0:tempBackposition;
        for (int i = tempBackposition; i < finalposition; i++)
        {
            output += splitedword[i] + " ";
        }
        Console.WriteLine(output);
        Console.ReadLine();

如果不是你想要的,你能在上面回答我的问题吗?或者帮我理解是不是错了

【讨论】:

  • 好吧,如果单词 Four 在开头,它不应该返回任何东西。你所做的假设是正确的。让我试一试,然后回复你。,
【解决方案2】:
int i ;
string outputString = (i=sentenceString.IndexOf(wordString))<0 ?     
                          sentenceString : sentenceString.Substring(0,i) ;

【讨论】:

  • 这只是返回了整个句子,而不是我想要的。
  • 抱歉,比较(即 ">=0")被颠倒了。我更新了代码。
  • 好的,所以它似乎在大多数情况下都有效,但有时它会为不同的情况返回空字符串,而为其他情况返回整个句子。
  • Correction [ 再次 :( ] 如果句子为空或单词字符串在句子的开头,则返回空字符串。如果单词字符串不在句子中,则返回完整的句子。
  • 好的,那么我需要考虑这两个用例......这仍然是一个好的开始。
【解决方案3】:
var wordString = "(Four)";
            int wordStringInt = 4; // Just do switch case to convert your string to int
            var sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
            var sentenceStringArray = sentenceString.Split(' ').ToList();
            int wordStringIndexInArray = sentenceStringArray.IndexOf(wordString) - 1;
            var stringOutPut = "";
            if (wordStringIndexInArray > 0 && wordStringIndexInArray > wordStringInt)
            {
                stringOutPut = "";
                while (wordStringInt > 0)
                {
                    stringOutPut = sentenceStringArray[wordStringInt] + " " + stringOutPut;
                    wordStringInt--;
                }

            }

【讨论】:

  • 在while末尾添加wordStringIndexInArray--;
  • 用那个替换字符串输出?
【解决方案4】:

您要匹配的内容有点复杂,因此对于更通用的解决方案,您可以使用正则表达式。

首先我们声明我们要搜索的内容:

string word = "(Four)";
string sentence = "Maybe the fowl of Uruguay repeaters (Four) will be found";

然后我们将使用正则表达式搜索此字符串中的单词。由于我们不想匹配空格,并且我们需要知道每个匹配实际从哪里开始,我们需要知道括号内的单词,我们告诉它我们可以选择想要开始和结束括号,但是我们还希望它们的内容匹配:

var words = Regex.Matches(sentence, @"[\p{Ps}]*(?<Content>[\w]+)[\p{Pe}]*").Cast<Match>().ToList();

[\p{Ps}] 表示我们想要打开标点符号([{ 等,而* 表示零个或多个。

接下来是一个名为 Content 的子捕获(由 ?&lt;Content&gt; 指定),带有一个或多个单词字符。 最后我们指定我们想要零个或多个结束标点符号。

然后我们需要在匹配列表中找到这个词:

var item = words.Single(x => x.Value == word);

那么我们需要找到这个item的索引:

int index = words.IndexOf(item);

此时我们只需要知道内容的长度即可:

var length = item.Groups["Content"].Length;

我们用这个长度在字符串中回溯 4 个单词

var start = words.Skip(index - length).First();

现在我们拥有了我们需要的一切:

var result = sentence.Substring(start.Index, item.Index - start.Index);

结果应包含fowl of Uruguay repeaters

edit:从单词而不是从内容中计算数量可能要简单得多。在这种情况下,完整的代码应该如下:

string word = "(Four)";
string sentence = "Maybe the fowl of Uruguay repeaters (Four) will be found";

var wordMatch = Regex.Match(word, @"[\p{Ps}]*(?<Content>[\w]+)[\p{Pe}]*");
var length = wordMatch.Groups["Content"].Length;

var words = Regex.Matches(sentence, @"\S+").Cast<Match>().ToList();
var item = words.Single(x => x.Value == word);
int index = words.IndexOf(item);


var start = words.Skip(index - length).First();
var result = sentence.Substring(start.Index, item.Index - start.Index);

\S+ 在这种情况下表示“匹配一个或多个非空白字符”。

【讨论】:

    【解决方案5】:

    您应该尝试以下类似的方法,它在找到数字单词后使用Array.Copy。您仍然需要正确实现 ConvertToNum 函数(它现在是硬编码的),但这应该是一个快速简单的解决方案。

    string[] GetWords()
    {
        string sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
        string[] words = sentenceString.Split();
        int num = 0;
        int i; // scope of i should remain outside the for loop
        for (i = 0; i < words.Length; i++)
        {
            string word = words[i];
            if (word.StartsWith("(") && word.EndsWith(")"))
            {
                num = ConvertToNum(word.Substring(1, word.Length - 1));
                // converted the number word we found, so we break
                break;
            }
        }
        if (num == 0)
        {
            // no number word was found in the string - return empty array
            return new string[0];
        }
            // do some extra checking if number word exceeds number of previous words
            int startIndex = i - num;
            // if it does - just start from index 0
            startIndex = startIndex < 0 ? 0 : startIndex;
            int length = i - startIndex;
            string[] output = new string[length];
            Array.Copy(words, startIndex, output, 0, length);
            return output;
    }
    
    
    // Convert the number word to an integer
    int ConvertToNum(string numberStr)
    {
        return 4; // you should implement this method correctly
    }
    

    请参阅 - Convert words (string) to Int,获取实施 ConvertToNum 解决方案的帮助。显然,它可以根据您希望处理的数字范围进行简化。

    【讨论】:

      【解决方案6】:

      这是我的解决方案,为了便于理解,我根本不使用正则表达式:

              static void Main() {
                  var wordString = "(Four)";
                  int wordStringLength = wordString.Replace("(","").Replace(")","").Length; 
                  //4, because i'm assuming '(' and ')' doesn't count. 
      
                  var sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
      
                  //Transform into a list of words, ToList() to future use of IndexOf Method
                  var sentenceStringWords = sentenceString.Split(' ').ToList();
      
                  //Find the index of the word in the list of words
                  int wordIndex = sentenceStringWords.IndexOf(wordString);
      
                  //Get a subrange from the original list of words, going back x Times the legnth of word (in this case 4),
      
                  var wordsToConcat = sentenceStringWords.GetRange(wordIndex-wordStringLength, wordStringLength);
      
                  //Finally concat the output;
                  var outPut = string.Join(" ", wordsToConcat);
      
                  //Output: fowl of Uruguay repeaters
      
              }
      

      【讨论】:

        【解决方案7】:

        我有一个解决方案:

        string wordToMatch = "(Four)";
                    string sentence = "Maybe the fowl of Uruguay repeaters (Four) will be found";
        
                    if (sentence.Contains(wordToMatch))
                    {
                        int length = wordToMatch.Trim(new[] { '(', ')' }).Length;
                        int indexOfMatchedWord = sentence.IndexOf(wordToMatch);
                        string subString1 = sentence.Substring(0, indexOfMatchedWord);
                        string[] words = subString1.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        var reversed = words.Reverse().Take(length);
        
                        string result = string.Join(" ", reversed.Reverse());
                        Console.WriteLine(result);
                        Console.ReadLine();
                    }
        

        这可能会在性能方面得到改善,但我感觉你并不关心这一点。确保您使用的是“System.Linq”

        【讨论】:

          【解决方案8】:

          我假设输入不完整时返回空,请随时纠正我。在您的帖子中没有 100% 清楚应该如何处理。

              private string getPartialSentence(string sentence, string word)
              {
                  if (string.IsNullOrEmpty(sentence) || string.IsNullOrEmpty(word))
                      return string.Empty;
          
                  int locationInSentence = sentence.IndexOf(word, StringComparison.Ordinal);
          
                  if (locationInSentence == -1)
                      return string.Empty;
          
                  string partialSentence = sentence.Substring(0, locationInSentence);
                  string[] words = partialSentence.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
          
                  int nbWordsRequired = word.Replace("(", "").Replace(")", "").Length;
          
                  if (words.Count() >= nbWordsRequired)
                      return String.Join(" ", words.Skip(words.Count() - nbWordsRequired));
          
                  return String.Join(" ", words);
              }
          

          【讨论】:

            【解决方案9】:

            我使用枚举和相关字典将“(四)”类型字符串与其整数值配对。您可以使用

            轻松(也许更容易)使用 switch 语句
            case "(Four)": { currentNumber = 4; };
            

            我觉得枚举允许更多的灵活性。

            public enum NumberVerb
                {
                    one = 1,
                    two = 2,
                    three = 3,
                    four = 4,
                    five = 5,
                    six = 6,
                    seven = 7,
                    eight = 8,
                    nine = 9,
                    ten = 10,
                };
            
                public static Dictionary<string, NumberVerb> m_Dictionary
                {
                    get
                    {
                        Dictionary<string, NumberVerb> temp = new Dictionary<string, NumberVerb>();
            
                        temp.Add("(one)", NumberVerb.one);
                        temp.Add("(two)", NumberVerb.two);
                        temp.Add("(three)", NumberVerb.three);
                        temp.Add("(four)", NumberVerb.four);
                        temp.Add("(five)", NumberVerb.five);
                        temp.Add("(six)", NumberVerb.six);
                        temp.Add("(seven)", NumberVerb.seven);
                        temp.Add("(eight)", NumberVerb.eight);
                        temp.Add("(nine)", NumberVerb.nine);
                        temp.Add("(ten)", NumberVerb.ten);
            
                        return temp;
                    }
                }
            
                static void Main(string[] args)
                {
                    string resultPhrase = "";
            
                    // Get the sentance that will be searched.
                    Console.WriteLine("Please enter the starting sentance:");
                    Console.WriteLine("(don't forget your keyword: ie '(Four)')");
                    string sentance = Console.ReadLine();
            
                    // Get the search word.
                    Console.WriteLine("Please enter the search keyword:");
                    string keyword = Console.ReadLine();
            
                    // Set the associated number of words to backwards-iterate.
                    int currentNumber = -1;
                    try 
                    {
                        currentNumber = (int)m_Dictionary[keyword.ToLower()];
                    }
                    catch(KeyNotFoundException ex)
                    {
                        Console.WriteLine("The provided keyword was not found in the dictionary.");
                    }
            
                    // Search the sentance string for the keyword, and get the starting index.
                    Console.WriteLine("Searching for phrase...");
            
                    string[] words = sentance.Split(' ');
                    int searchResultIndex = -1;
            
                    for (int i = 0; (searchResultIndex == -1 && i < words.Length); i++)
                    {
                        if (words[i].Equals(keyword))
                        {
                            searchResultIndex = i;
                        }
                    }
            
                    // Handle the search results.
                    if (searchResultIndex == -1)
                    {
                        resultPhrase = "The keyword was not found.";
                    }
                    else if (searchResultIndex < currentNumber)
                    {
                        // Check the array boundaries with the given indexes.
                        resultPhrase = "Error: Out of bounds!";
                    }
                    else
                    {
                        // Get the preceding words.
                        for (int i = 0; i < currentNumber; i++)
                        {
                            resultPhrase = string.Format(" {0}{1}", words[searchResultIndex - 1 - i], resultPhrase);
                        }
                    }
            
                    // Display the preceding words.
                    Console.WriteLine(resultPhrase.Trim());
            
                    // Exit.
                    Console.ReadLine();
                }
            

            【讨论】:

              猜你喜欢
              • 2015-09-25
              • 2021-11-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-15
              • 1970-01-01
              • 2012-01-31
              • 2023-01-31
              相关资源
              最近更新 更多