如何更改此代码以获取正确的输出(C++)

发布于 2025-02-07 12:23:30 字数 1281 浏览 3 评论 0原文

程序应从用户中获取输入单词,只有一个字母差打印出所有文件中的所有单词。例如:如果输入为:“ way” 输出应为 [例如,五月,战争,战争,蜡,蜡,是...] 我的代码是找到单词仅使用输入的确切单词。就像输入是“ start” ,输出为 [重新启动,启动,启动...] 如何更改它以像上述示例一样获取输出?这是一个代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

void fileRead(vector<string>& v, ifstream& fin) {
    string line;
    while (getline(fin, line)) {
        v.push_back(line);
    }
}
void search(vector<string>& v, string word) {
    for (int i = 0; i < v.size(); i++) {
        int index = v[i].find(word);
        if (index != -1)
            cout << v[i] << endl;
    }
}
int main() {
    vector<string> wordVector;
    ifstream fin("text.txt");
    if (!fin) {
        cout << "text.txt can't opened" << endl;
        return 0;
    }
    fileRead(wordVector, fin);
    fin.close();
    cout << "reading text.txt." << endl;
    while (true) {
        cout << "Input a word: >>";
        string word;
        getline(cin, word);
        if (word == "exit")
            break;
        search(wordVector, word);
    }
    cout << "Terminated" << endl;
}

Program should take input word from user and print out all the words in file with only one letter difference. For example: if input is: "way" output should be [say, may, day, war, waw, wax, was...]
My code is finding words only with exact word which inputed. Like if input is "start", output is [restart, startup, started...] How can I change it to get output like above example? Here is a code:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

void fileRead(vector<string>& v, ifstream& fin) {
    string line;
    while (getline(fin, line)) {
        v.push_back(line);
    }
}
void search(vector<string>& v, string word) {
    for (int i = 0; i < v.size(); i++) {
        int index = v[i].find(word);
        if (index != -1)
            cout << v[i] << endl;
    }
}
int main() {
    vector<string> wordVector;
    ifstream fin("text.txt");
    if (!fin) {
        cout << "text.txt can't opened" << endl;
        return 0;
    }
    fileRead(wordVector, fin);
    fin.close();
    cout << "reading text.txt." << endl;
    while (true) {
        cout << "Input a word: >>";
        string word;
        getline(cin, word);
        if (word == "exit")
            break;
        search(wordVector, word);
    }
    cout << "Terminated" << endl;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难忘№最初的完美 2025-02-14 12:23:30

我写了此功能find_all_alternate找到给定单词的所有可能替代方案。

我从此处列出了单词列表

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <iterator>
#include <set>

// type alias
using word_list_t = std::vector<std::string>;
using word_t = std::string;

// find all alternative occurrence of a word in the given list
void find_all_alternate(word_list_t &list, word_t word)
{
    word_list_t search_list;

    // Filter out bigger words
    std::copy_if(list.begin(), list.end(),
                std::back_inserter(search_list),
                [=](auto s){
                    return s.size() == word.size();
    });

    auto len = word.size();
    std::set<std::string> results;

    while(len--) {
        std::string alt = word.substr(1, word.size()-1);
        for(const auto& w : search_list) {
            auto found = w.find(alt);
            if(found != std::string::npos) {
                results.insert(w);
            }
        }
        std::rotate(word.begin(), word.begin()+1, word.end());
    }

    std::cout << "All possible alternatives of word '" << word << "' are: " << std::endl;
    for(const auto &s : results) std::cout << s << std::endl;
    std::cout << std::endl;
}

int main(int argc, char *argv[])
{
    if(argc != 2) {
        std::cerr << "ERROR: Run the program as follows\n";
        std::cerr << "./word_search <word>\n";
        return -1;
    }

    std::string word_to_search = argv[1];
    std::ifstream in_file("words.txt", std::ios::in);
    if(!in_file.is_open()) {
        std::cerr << "Unable to open words.txt file\n";
        return -1;
    }

    std::string word;
    word_list_t word_list;

    while(in_file >> word) {
        word_list.push_back(word);
    }
    in_file.close();

    find_all_alternate(word_list, word_to_search);
}

编译和运行

g++ -Wall -Wextra -Wpedantic -std=c++17 word_search.cpp -o word_search
./word_search  say

输出

All possible alternatives of word 'say' are:
aye
bay
day
gay
hay
isa
jay
kay
lay
may
pay
ray
sad
sam
san
sao
sap
sas
sat
saw
say
sys

I wrote this function find_all_alternate to find all possible alternate of a given word.

I've taken the list of words from here

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <iterator>
#include <set>

// type alias
using word_list_t = std::vector<std::string>;
using word_t = std::string;

// find all alternative occurrence of a word in the given list
void find_all_alternate(word_list_t &list, word_t word)
{
    word_list_t search_list;

    // Filter out bigger words
    std::copy_if(list.begin(), list.end(),
                std::back_inserter(search_list),
                [=](auto s){
                    return s.size() == word.size();
    });

    auto len = word.size();
    std::set<std::string> results;

    while(len--) {
        std::string alt = word.substr(1, word.size()-1);
        for(const auto& w : search_list) {
            auto found = w.find(alt);
            if(found != std::string::npos) {
                results.insert(w);
            }
        }
        std::rotate(word.begin(), word.begin()+1, word.end());
    }

    std::cout << "All possible alternatives of word '" << word << "' are: " << std::endl;
    for(const auto &s : results) std::cout << s << std::endl;
    std::cout << std::endl;
}

int main(int argc, char *argv[])
{
    if(argc != 2) {
        std::cerr << "ERROR: Run the program as follows\n";
        std::cerr << "./word_search <word>\n";
        return -1;
    }

    std::string word_to_search = argv[1];
    std::ifstream in_file("words.txt", std::ios::in);
    if(!in_file.is_open()) {
        std::cerr << "Unable to open words.txt file\n";
        return -1;
    }

    std::string word;
    word_list_t word_list;

    while(in_file >> word) {
        word_list.push_back(word);
    }
    in_file.close();

    find_all_alternate(word_list, word_to_search);
}

Compilation and running

g++ -Wall -Wextra -Wpedantic -std=c++17 word_search.cpp -o word_search
./word_search  say

Output

All possible alternatives of word 'say' are:
aye
bay
day
gay
hay
isa
jay
kay
lay
may
pay
ray
sad
sam
san
sao
sap
sas
sat
saw
say
sys
月亮坠入山谷 2025-02-14 12:23:30

您的程序显示了此结果,因为std :: String 查找功能只会查找基因的确切匹配。

您想要的是计算2个字符串的距离,然后显示1个距离为1的距离。

对于计算距离,通常使用众所周知的 levensthein 算法。

我在答案中显示了一个实现 and 在这里

这样,您的解决方案可以修改为以为

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <numeric>

using namespace std;


// Distance between 2 strings
size_t levensthein(const std::string& string1, const std::string& string2)
{
    // First get the string lengths
    const size_t lengthString1{ string1.size() };
    const size_t lengthString2{ string2.size() };

    // If one of the string length is 0, then return the length of the other
    // This results in 0, if both lengths are 0
    if (lengthString1 == 0) return lengthString2;
    if (lengthString2 == 0) return lengthString1;

    // Initialize substitition cost vector
    std::vector<size_t> substitutionCost(lengthString2 + 1);
    std::iota(substitutionCost.begin(), substitutionCost.end(), 0);

    // Calculate substitution cost
    for (size_t indexString1{}; indexString1 < lengthString1; ++indexString1) {
        substitutionCost[0] = indexString1 + 1;
        size_t corner{ indexString1 };

        for (size_t indexString2{}; indexString2 < lengthString2; ++indexString2) {
            size_t upper{ substitutionCost[indexString2 + 1] };
            if (string1[indexString1] == string2[indexString2]) {
                substitutionCost[indexString2 + 1] = corner;
            }
            else {
                const size_t temp = std::min(upper, corner);
                substitutionCost[indexString2 + 1] = std::min(substitutionCost[indexString2], temp) + 1;
            }
            corner = upper;
        }
    }
    return substitutionCost[lengthString2];
}


void fileRead(vector<string>& v, ifstream& fin) {
    string line;
    while (getline(fin, line)) {
        v.push_back(line);
    }
}
void search(vector<string>& v, string word) {
    for (int i = 0; i < v.size(); i++) {
        int distance = levensthein(word,v[i]);
        if (distance == 1)
            cout << v[i] << endl;
    }
}
int main() {
    vector<string> wordVector;
    ifstream fin("text.txt");
    if (!fin) {
        cout << "text.txt can't opened" << endl;
        return 0;
    }
    fileRead(wordVector, fin);
    fin.close();
    cout << "reading text.txt." << endl;
    while (true) {
        cout << "Input a word: >>";
        string word;
        getline(cin, word);
        if (word == "exit")
            break;
        search(wordVector, word);
    }
    cout << "Terminated" << endl;
}

,如果要将其转换为更现代的C ++,也可以使用:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>

// Distance between 2 strings
size_t levensthein(const std::string& string1, const std::string& string2)
{
    // First get the string lengths
    const size_t lengthString1{ string1.size() };
    const size_t lengthString2{ string2.size() };

    // If one of the string length is 0, then return the length of the other
    // This results in 0, if both lengths are 0
    if (lengthString1 == 0) return lengthString2;
    if (lengthString2 == 0) return lengthString1;

    // Initialize substitition cost vector
    std::vector<size_t> substitutionCost(lengthString2 + 1);
    std::iota(substitutionCost.begin(), substitutionCost.end(), 0);

    // Calculate substitution cost
    for (size_t indexString1{}; indexString1 < lengthString1; ++indexString1) {
        substitutionCost[0] = indexString1 + 1;
        size_t corner{ indexString1 };

        for (size_t indexString2{}; indexString2 < lengthString2; ++indexString2) {
            size_t upper{ substitutionCost[indexString2 + 1] };
            if (string1[indexString1] == string2[indexString2]) {
                substitutionCost[indexString2 + 1] = corner;
            }
            else {
                const size_t temp = std::min(upper, corner);
                substitutionCost[indexString2 + 1] = std::min(substitutionCost[indexString2], temp) + 1;
            }
            corner = upper;
        }
    }
    return substitutionCost[lengthString2];
}


int main() {
    // Open file and check, if it could be opened
    if (std::ifstream fin("text.txt"); fin) {

        // Read all words from the file
        std::vector words(std::istream_iterator<std::string>(fin), {});

        // Read words to search for, until user enters exit
        std::string word{};
        while (word != "exit") {

            // Tell user, what to do
            std::cout << "\n\nInput a word: >> ";

            // Show result
            if (std::getline(std::cin, word) and word != "exit")
                std::copy_if(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"), [&](const std::string& s) { return 1u == levensthein(s, word); });
        }
    }
    else std::cerr << "\nError. Could not open source file\n\n";
}

如果有限制只有相等长度的单词,则可以编写一个简单的比较函数你自己。

看起来像:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>

bool oneLetterDifferent(const std::string& string1, const std::string& string2) {
    bool equalLength{ string1.length() == string2.length() };

    unsigned int unequalCounter{};
    if (equalLength) for (size_t i{}; i < string1.length(); ++i) {
        if (string1[i] != string2[i])
            ++unequalCounter;
    }
    return equalLength and (unequalCounter < 2);
}

int main() {
    // Open file and check, if it could be opened
    if (std::ifstream fin("text.txt"); fin) {

        // Read all words from the file
        std::vector words(std::istream_iterator<std::string>(fin), {});

        // Read words to search for, until user enters exit
        std::string word{};
        while (word != "exit") {

            // Tell user, what to do
            std::cout << "\n\nInput a word: >> ";

            // Show result
            if (std::getline(std::cin, word) and word != "exit")
                std::copy_if(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"), [&](const std::string& s) { return oneLetterDifferent(s, word); });
        }
    }
    else std::cerr << "\nError. Could not open source file\n\n";
}

Your program shows this result, because the std::string find function will only look for an exact match of a substring.

What you want is to calculate the distance of 2 strings and then show those with a distance of 1.

For calculating the distance, generally the well known Levensthein algorithm is used.

I showed an implementation already in my answers here and here.

With that, your solution can be modified to

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <numeric>

using namespace std;


// Distance between 2 strings
size_t levensthein(const std::string& string1, const std::string& string2)
{
    // First get the string lengths
    const size_t lengthString1{ string1.size() };
    const size_t lengthString2{ string2.size() };

    // If one of the string length is 0, then return the length of the other
    // This results in 0, if both lengths are 0
    if (lengthString1 == 0) return lengthString2;
    if (lengthString2 == 0) return lengthString1;

    // Initialize substitition cost vector
    std::vector<size_t> substitutionCost(lengthString2 + 1);
    std::iota(substitutionCost.begin(), substitutionCost.end(), 0);

    // Calculate substitution cost
    for (size_t indexString1{}; indexString1 < lengthString1; ++indexString1) {
        substitutionCost[0] = indexString1 + 1;
        size_t corner{ indexString1 };

        for (size_t indexString2{}; indexString2 < lengthString2; ++indexString2) {
            size_t upper{ substitutionCost[indexString2 + 1] };
            if (string1[indexString1] == string2[indexString2]) {
                substitutionCost[indexString2 + 1] = corner;
            }
            else {
                const size_t temp = std::min(upper, corner);
                substitutionCost[indexString2 + 1] = std::min(substitutionCost[indexString2], temp) + 1;
            }
            corner = upper;
        }
    }
    return substitutionCost[lengthString2];
}


void fileRead(vector<string>& v, ifstream& fin) {
    string line;
    while (getline(fin, line)) {
        v.push_back(line);
    }
}
void search(vector<string>& v, string word) {
    for (int i = 0; i < v.size(); i++) {
        int distance = levensthein(word,v[i]);
        if (distance == 1)
            cout << v[i] << endl;
    }
}
int main() {
    vector<string> wordVector;
    ifstream fin("text.txt");
    if (!fin) {
        cout << "text.txt can't opened" << endl;
        return 0;
    }
    fileRead(wordVector, fin);
    fin.close();
    cout << "reading text.txt." << endl;
    while (true) {
        cout << "Input a word: >>";
        string word;
        getline(cin, word);
        if (word == "exit")
            break;
        search(wordVector, word);
    }
    cout << "Terminated" << endl;
}

And if you want to convert this to more modern C++, you can also use:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>

// Distance between 2 strings
size_t levensthein(const std::string& string1, const std::string& string2)
{
    // First get the string lengths
    const size_t lengthString1{ string1.size() };
    const size_t lengthString2{ string2.size() };

    // If one of the string length is 0, then return the length of the other
    // This results in 0, if both lengths are 0
    if (lengthString1 == 0) return lengthString2;
    if (lengthString2 == 0) return lengthString1;

    // Initialize substitition cost vector
    std::vector<size_t> substitutionCost(lengthString2 + 1);
    std::iota(substitutionCost.begin(), substitutionCost.end(), 0);

    // Calculate substitution cost
    for (size_t indexString1{}; indexString1 < lengthString1; ++indexString1) {
        substitutionCost[0] = indexString1 + 1;
        size_t corner{ indexString1 };

        for (size_t indexString2{}; indexString2 < lengthString2; ++indexString2) {
            size_t upper{ substitutionCost[indexString2 + 1] };
            if (string1[indexString1] == string2[indexString2]) {
                substitutionCost[indexString2 + 1] = corner;
            }
            else {
                const size_t temp = std::min(upper, corner);
                substitutionCost[indexString2 + 1] = std::min(substitutionCost[indexString2], temp) + 1;
            }
            corner = upper;
        }
    }
    return substitutionCost[lengthString2];
}


int main() {
    // Open file and check, if it could be opened
    if (std::ifstream fin("text.txt"); fin) {

        // Read all words from the file
        std::vector words(std::istream_iterator<std::string>(fin), {});

        // Read words to search for, until user enters exit
        std::string word{};
        while (word != "exit") {

            // Tell user, what to do
            std::cout << "\n\nInput a word: >> ";

            // Show result
            if (std::getline(std::cin, word) and word != "exit")
                std::copy_if(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"), [&](const std::string& s) { return 1u == levensthein(s, word); });
        }
    }
    else std::cerr << "\nError. Could not open source file\n\n";
}

And if there is the restriction that only words of equal length shall be shown, then you can write a simple comparison function by yourself.

This would look like:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>

bool oneLetterDifferent(const std::string& string1, const std::string& string2) {
    bool equalLength{ string1.length() == string2.length() };

    unsigned int unequalCounter{};
    if (equalLength) for (size_t i{}; i < string1.length(); ++i) {
        if (string1[i] != string2[i])
            ++unequalCounter;
    }
    return equalLength and (unequalCounter < 2);
}

int main() {
    // Open file and check, if it could be opened
    if (std::ifstream fin("text.txt"); fin) {

        // Read all words from the file
        std::vector words(std::istream_iterator<std::string>(fin), {});

        // Read words to search for, until user enters exit
        std::string word{};
        while (word != "exit") {

            // Tell user, what to do
            std::cout << "\n\nInput a word: >> ";

            // Show result
            if (std::getline(std::cin, word) and word != "exit")
                std::copy_if(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"), [&](const std::string& s) { return oneLetterDifferent(s, word); });
        }
    }
    else std::cerr << "\nError. Could not open source file\n\n";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文