【问题标题】:How can I check if 2 subwords from a vector match a user inputted string?如何检查向量中的 2 个子词是否与用户输入的字符串匹配?
【发布时间】:2021-05-17 21:15:47
【问题描述】:
  1. 我正在做一个项目,在该项目中我从一个文本文件中遍历数百个单词的列表。该文件名为 words.txt

  2. 我要求用户输入一个单词,然后从给定的单词中找到所有长度大于 2 个字符且由用户指定单词中的字母组成的“不区分大小写”子单词。

  3. 例如:如果用户输入单词“Winter”,它会有“win”、“int”、“wit”、“wire”、“rent”、“tin”、“twin”等子词, “新的”,。 所有这些单词都包含在文本文件中(非常大)。

  4. 我知道有一种方法可以检查单词是否匹配,但如果长度大于两个字符,我特别需要它来工作

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)
{
  
  

}


}

【问题讨论】:

  • 你的描述不清楚,至少对我来说是这样。 在文件中找到了多少次 2 个子字符串 -- 在哪里和/或什么产生了这些子字符串?他们输入了吗?它们是计算出来的吗?如果有 10 个这样的子串怎么办?你取子串 1 和子串 2,加总,然后子串 1 和子串 3,加总等等?
  • 这个问题可能不适合 SO。您说您知道如何迭代单词列表 - 实现它并尝试首先自己解决“两个匹配的子字符串”部分。当您遇到困难或遇到特定问题时,请编辑您的问题以反映这一点。

标签: c++ string loops vector substring


【解决方案1】:

其中一个非常简单有效的解决方案是将您的单词转换为字母计数数组(在此之前将它们更改为小写)。它可以是std::map&lt;char,int&gt;std::unordered_map&lt;char,int&gt;std::array&lt;int,26&gt;(其中索引0 代表'a',1 - 'b' 等等)。那么文件中的单词是您输入的子词当且仅当文件中单词中每个字母的计数小于或等于用户输入中相同字母的计数。

例如单词“winter”将表示为:

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

所以

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

但是

"war" which is 'w' - 1, 'a' - 1, 'r' - 1 is not, because count of 'a' is 0 in "winter"

【讨论】:

    【解决方案2】:

    我不太确定我是否正确理解了您的问题,但是如果您想检查用户的输入是否是您的单词向量中任何单词的子字符串,那么 Check if a string contains a string in C++ 可能就是您要查找的内容。

    您可以执行以下操作来计算在您的向量的任何单词中找到inputUser 的次数:

    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;
    

    在本例中,输出为2

    编辑(编辑问题后)

    我认为我现在理解了您的问题,我认为这可能是您正在寻找的:

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

    在此示例中,将getSubStrings(temp, inputOfUser.size()) 分配给subStrings 后,subStrings 将如下所示:

    我从https://www.geeksforgeeks.org/program-print-substrings-given-string/ 中提取了getSubStrings() 方法,并对其进行了一些修改,因此它适合您的情况:

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

    对于给定的示例,结果如下(请记住,单词看起来像这样std::vector&lt;std::string&gt; words = { "Winter", "Summer", "Autmn", "inter" }; 输入看起来像这样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
    

    【讨论】:

    • 我编辑了我的问题以指定只要匹配的子字符串大于两个字符。很抱歉造成混乱,但这似乎是我需要的那种东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2017-01-31
    • 2022-01-24
    • 2018-10-02
    • 1970-01-01
    相关资源
    最近更新 更多