-2
  1. I am working on a project where I iterate through a list of hundreds of words from a text file. The file is named words.txt

  2. I ask the user to input a word and from the given word, find all the "case-insensitive" sub-words whose length is greater than 2 characters and made from the letters in the user-specified word.

  3. FOR EXAMPLE: if the user inputted the word, "Winter", it would have the subwords of "win", "int", "wit", "wire", "rent", "tin", "twin", "new",. All of these words are contained in the text file (it is very large).

  4. I know there is a way to check if the word matches but I specifically need it to work if the length is greater than two characters

void subWord()

{
  // user inputted word init
  std::string userInputWord = {};
  //input file stream object
std::ifstream file("words.txt");
// this vector will hold the list of words inputted from the while loop
std::vector<std::string> words;
std::string input;
// this loop continues as long as the read is successful and there is no more words to read
while(file >> input)
{
  words.push_back(input);
}

std::cout << "Please enter a word: " << std::endl;
std::cin >> userInputWord;
// counter to keep track of times 2 characters match
int counter = 0;

// I know this how I would iterate over the list of words but then I need a way to check for two matching substrings
for (std::string word : words)
{
  
  

}


}
  • Your description is not clear, at least to me. *how many times 2 sub strings are found in the file* -- Where and/or what produces these substrings? Are they inputted? Are they computed? What if there are 10 such substring? Do you take substring 1 and substring 2, add up the total, and then substring 1 and substring 3, add up the total, etc? – PaulMcKenzie Feb 14 '21 at 21:39
  • This question might not be the best fit for SO. You say you know how you would iterate over the list of words - implement that and try solving the "two matching substrings" part on your own first. When you get stuck or have a specific issue, edit your question to reflect that. – Nick Reed Feb 14 '21 at 21:39

2 Answers2

0

One of the quite simple and efficient solution would be to convert your words into array of letter count (change them to lowercase before that). It could be std::map<char,int> or std::unordered_map<char,int> or std::array<int,26> (where index 0 represents 'a', 1 - 'b' and so on). Then a word from a file is a subword of your input if and only if count of every letter in a word from file is less or equal than count of the same letter in user input.

For example word "winter" will be represented as:

'w' - 1, 'i' - 1, 'n' - 1, 't' - 1, 'e' - 1, 'r' - 1

so

"int" which is 'i' - 1, 'n' - 1, 't' - 1 is a subword

but

"war" which is 'w' - 1, 'a' - 1, 'r' - 1 is not, because count of 'a' is 0 in "winter"
Slava
  • 43,454
  • 1
  • 47
  • 90
0

I am not quite sure if I understood your question right, but if you want to check if the input of the user is a substring of any word in your words vector, then Check if a string contains a string in C++ might be what you are looking for.

You could do the following to count the amount of times inputUser was found in any word of your vector :

std::vector<std::string> words = { "Winter", "Summer", "Autmn", "inter" };
    std::string inputOfUser = "int";
    int countMatches = 0;

    for (std::string word : words) {
        if (word.find(inputOfUser) != std::string::npos) {
            countMatches++;
        }
    }
    
    std::cout << countMatches << std::endl;

In this example the output would be 2

EDIT (after question was edited)

As I think that I understood your problem now, I think this is probably what you are looking for:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>


std::vector<std::string> getSubStrings(char[], int n);

int main()
{
    std::vector<std::string> words = { "winter", "summer", "autmn", "inter" };
    std::string inputOfUser = "Winter";
    std::vector<std::string> subStrings;

    //transform the input to lower-case
    std::transform(inputOfUser.begin(), inputOfUser.end(), inputOfUser.begin(), ::tolower);
    //as getSubString requires a char[]
    char* temp = &inputOfUser[0];

    subStrings = getSubStrings(temp, inputOfUser.size());

    // go through every substring 
    for (std::string subString : subStrings) {
        std::cout << std::endl << "looking for substring: " << subString << std::endl;
// go through every word of your vector
        for (std::string word : words) {
            // does the word contain the substring? 
            if (word.find(subString) != std::string::npos){
                // yes, it does
                std::cout << "found: " << subString << " in word: " << word << std::endl;
            }
            //else: it does not 
        }
    }
}

In this example, after getSubStrings(temp, inputOfUser.size()) is assigned to subStrings, subStrings would look like the following:

content of subString variable

I took the getSubStrings() method from https://www.geeksforgeeks.org/program-print-substrings-given-string/ and modified it a little bit, so it would fit for your case:

std::vector<std::string> getSubStrings(char str[], int n)
{
    std::vector<std::string> subStrings;
    // Pick starting point
    for (int len = 1; len <= n; len++)
    {

        // Pick ending point
        for (int i = 0; i <= n - len; i++)
        {
            std::string tempSub = "";
            // take only the substrings that are greater than 2 in size  
            if (len > 2) {
            // Add characters from current
            // starting point to current ending
            // point to tempSub
                int j = i + len - 1;
                for (int k = i; k <= j; k++) {
                    tempSub += str[k];
                }
                // push the resulted substring into subStrings
                subStrings.push_back(tempSub);
            }
        }
    }
    return subStrings;
}

For the given example, the following would be the result ( remember, words looked like this std::vector<std::string> words = { "Winter", "Summer", "Autmn", "inter" }; and the input looked like this std::string inputOfUser = "Winter" :

looking for substring: win
found: win in word: winter

looking for substring: int
found: int in word: winter
found: int in word: inter

looking for substring: nte
found: nte in word: winter
found: nte in word: inter

looking for substring: ter
found: ter in word: winter
found: ter in word: inter

looking for substring: wint
found: wint in word: winter

looking for substring: inte
found: inte in word: winter
found: inte in word: inter

looking for substring: nter
found: nter in word: winter
found: nter in word: inter

looking for substring: winte
found: winte in word: winter

looking for substring: inter
found: inter in word: winter
found: inter in word: inter

looking for substring: winter
found: winter in word: winter
L.Gashi
  • 183
  • 1
  • 11
  • I edited my question to specify that as long as the matching substring is greater than two character. Sorry for the confusion but this seems like the kind of thing that I would need. – lonewanderer Feb 14 '21 at 22:05