-2

I've got a project I'm working on in C#. I've got two char array's. One is a sentence and one is a word. I've got to iterate through the sentence array until I find a word that matches the word that was turned into an word array what I'm wondering is once I find the word how do I iterate backwards through the sentence array at the point I found the word back through the same length as the word array?

Code :

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.
      }

I don't know if I'm being clear enough on this but if I'm not please feel free to ask.. Thank you in advanced. Also what this should return is "fowl of Uruguay repeaters". So basically the use case is for the number of letters in the parenthesis the logic should return the same number of words before the word in parenthesis.

yams
  • 942
  • 6
  • 27
  • 60
  • You must use only char array?? and what exactly the output should be? – Kram Jul 14 '15 at 20:45
  • No it shouldn't that is just what I was thinking of using don't know if that is the best way. The output of this should return "fowl of Uruguay repeaters" – yams Jul 14 '15 at 20:46
  • 3
    What prevents you from using sentenceString.IndexOf(wordString) ? – Graffito Jul 14 '15 at 20:47
  • Use a combination of indexOf, Substring, etc. – George Lica Jul 14 '15 at 20:51
  • Like I said I just used what came to mind. – yams Jul 14 '15 at 21:08
  • Oh look a down vote and a close. Seems a moderator here is trying to bully again. – yams Jul 14 '15 at 21:36
  • 1
    Why should the output return "fowl of Uruguay repeaters" and not "Maybe the fowl of Uruguay repeaters"? – cost Jul 14 '15 at 21:53
  • It's a requirement for the assignment. – yams Jul 14 '15 at 21:57
  • Basically it should count the number of letters in the word string then iterate back that number through the sentence. – yams Jul 14 '15 at 21:57
  • I would like to help, but I am confused. I can think of about five ways to do this, but I'm just not sure I understand what you are looking for. So I'm going to rewrite your question in my words and let's see if we can clarify things. I think you are saying that you have two arrays of letters (not words). One is longer than the other. I think you are saying that you need to compare letter by letter until you find a sequence of letters in the long array that matches all the letters in the small array. Am I right so far? – Guy Schalnat Jul 17 '15 at 01:14
  • Ok so you are partially right. Thank you for asking me this. There are two arrays. One is a sentence broken into a list. "Maybe the fowl of Uruguay repeaters (Four) will be found" The second is the word "Four" which I broke into an array. I need to iterate through the list of the words from the sentence backwards from the point the word "Four" was found the same number as the array does this help? – yams Jul 17 '15 at 17:00
  • PS I edited my question to show that I split the sentence into a list to iterate through. – yams Jul 17 '15 at 17:01
  • What is the rule that causes you to remove "Maybe the " from the expected result. Without knowing what input causes that removal, it is hard to produce an answer that will work for you. – Hypnovirus Jul 22 '15 at 16:21
  • Also, does the string to find have to be a word that matches a whole word in the sentence? What if the word was "(Fou"? Would the expected result be the same or "not found"? – Hypnovirus Jul 22 '15 at 16:23
  • Well. The length of the word Four determines how many words it should go back + 1 so it doesn't return the word four as well. – yams Jul 22 '15 at 18:05
  • Question is unclear. Please rephrase – AdityaKapreShrewsburyBoston Jul 23 '15 at 21:26

9 Answers9

2
int i ;
string outputString = (i=sentenceString.IndexOf(wordString))<0 ?     
                          sentenceString : sentenceString.Substring(0,i) ;
Graffito
  • 1,658
  • 1
  • 11
  • 10
  • This just returned the entire sentence not what I was looking for. – yams Jul 14 '15 at 21:29
  • sorry, the comparizon (i.e. ">=0") was inverted. I updated the code. – Graffito Jul 14 '15 at 21:31
  • Ok so it seems to work a majority of the time but sometimes it is returning empty strings for different cases and the whole sentence for others. – yams Jul 14 '15 at 21:38
  • Correction [ again :( ] It returns empty string if sentence is empty or if wordstring is at beginning of sentence. It returns full sentence if wordstring not in sentence. – Graffito Jul 14 '15 at 21:51
  • Ok so I need to account for those two use cases then...... This is still a good start. – yams Jul 14 '15 at 21:54
2
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--;
                }

            }
Kram
  • 526
  • 5
  • 11
2

our are you. I have few question concerned to this exercise. If the Word (four) was in beginning it should not return? or return all string? As the length of four is equal to 4 imagine if that word appear as the second word on sentence what it should return just the first word or return 4 words even including the (four) word.?

My solution is the laziest one I just see your question and decide to help.

  • My solution assumes it return all the word before the (four) if the length is bigger than the word before the (four) word.
  • My solution return empty string if the word (four) is in the beginning.
  • My solution return Length of (four) (4) words before (four) word.

ONCE AGAIN IT IS NOT MY BEST APPROACH.

I see the code bellow:

        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();

If it's not what you want can you answer my questions on top? or help me to understand were it's wrong

Felicio Balane
  • 301
  • 1
  • 8
  • Well if the word Four was in the beginning it shouldn't return anything. The assumptions you made where correct. Let me try it out and get back to you., – yams Jul 21 '15 at 15:12
2

What you are matching is kind of complex, so for a more general solution you could use regular expressions.

First we declare what we are searching for:

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

We will then search for the words in this string using regular expressions. Since we don't want to match whitespace, and we need to know where each match actually starts and we need to know the word inside the parenthesis we tell it that we optionally want opening and ending parenthesis, but we also want the contents of those as a match:

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

[\p{Ps}] means we want opening punctuation ([{ etc. while the * indicates zero or more.

Followed is a sub-capture called Content (specified by ?<Content>) with one or more word characters. At the end we specify that we want zero or more ending punctuation.

We then need to find the word in the list of matches:

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

Then we need to find this item's index:

int index = words.IndexOf(item);

At this point we just need to know the length of the contents:

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

This length we use to go back in the string 4 words

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

And now we have everything we need:

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

Result should contain fowl of Uruguay repeaters.

edit: It may be a lot simpler to just figure out the count from the word rather than from the content. In that case the complete code should be the following:

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+ in this case means "match one or more non-whitespace character".

GeirGrusom
  • 999
  • 5
  • 18
2

You should try something like the following, which uses Array.Copy after it finds the number word. You will still have to implement the ConvertToNum function correctly (it is hardcoded in for now), but this should be a quick and easy solution.

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
}

See - Convert words (string) to Int, for help implementing the ConvertToNum solution. Obviously it could be simplified depending on the range of numbers you expect to deal with.

Community
  • 1
  • 1
James Buck
  • 1,640
  • 9
  • 13
2

Here is my solution, im not using regex at all, for the sake of easy understanding:

        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

        }
George
  • 777
  • 7
  • 17
0

I have a solution for you:

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

Likely this can be improved regardng performance, but I have a feeling you don't care about that. Make sure you are using 'System.Linq'

Matt
  • 6,787
  • 11
  • 65
  • 112
0

I assumed empty returns when input is incomplete, feel free to correct me on that. Wasn't 100% clear in your post how this should be handled.

    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);
    }
Saragis
  • 1,782
  • 6
  • 21
  • 30
0

I went with using an enumeration and associated dictionary to pair the "(Four)" type strings with their integer values. You could just as easily (and maybe easier) go with a switch statement using

case "(Four)": { currentNumber = 4; };

I feel like the enum allows a little more flexibility though.

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();
    }
Kevin
  • 151
  • 3
  • 11