【问题标题】:Overloading Operator and vector STL problems重载运算符和向量 STL 问题
【发布时间】:2022-01-05 01:37:15
【问题描述】:

我有一个任务:从 EnglishWords.txt 中实现 60.000 个英文单词,然后对其进行排序和搜索。

我已经使用自定义 MergeSort 和 find_if STL 完成了排序和线性搜索,但是当我尝试使用其他向量 STL 时,例如 upper_bound、lower_bound、binary_search,它会导致以下一些问题:

  • 如果运行 lower_bound 函数,它不会返回与“手动搜索”函数相同的“索引”。
  • 不能将“MatchString”(我的重载运算符)用于 lower_bound 和 binary_search ST 或其他向量 STL 并返回 C2672 和 C2893 代码。
  • 另外,有人可以给我一些关于按字母“排序”的建议吗?

我的完整代码在https://onlinegdb.com/l4pfS9pYJ,请点击“Fork this”编辑代码。

一些额外的要求和概念。

  • 我是 OOP 新手,因此请向我展示一些建议,以提高我的代码编写技能。
  • 不要使用 STL sort(),自己写。
  • 必须将所有排序、搜索和工作功能放到 FastDictionary 中。

下面是我的重载运算符和有问题的函数。

void searchmanually(vector<Dictionary> list, string value)
{
    vector<Dictionary>::iterator it;
    it = find_if(list.begin(), list.end(), FastDictionary::MatchString(value));
    if (it != list.end())
    {
        auto idx = distance(list.begin(), it);
        cout << "Index = " << idx << endl;
    }
    else
    {
        cout << "Can not find the value !." << endl;
    }
}
void binary_search_find_index(vector<Dictionary> list, string value)
{
    vector<Dictionary>::iterator it1;
    it1 = lower_bound(list.begin(), list.end(), FastDictionary::MatchString(value));
    if (it1 != list.end())
    {
        auto idx1 = distance(list.begin(), it1);
        cout << "Index = " << idx1 << endl;
    }
    else
    {
        cout << "Can not find the value !." << endl;
    }
}
struct MatchString
{
private:
    const std::string& s_;
public:
    MatchString(const std::string& s) : s_(s) {}
    bool operator()(const Dictionary& obj) const
    {
        return obj._word == s_;
    }
    friend bool operator<(const Dictionary& obj, const MatchString &str) 
    {
        return obj._word < str.s_;
    }
    friend bool operator>(const Dictionary& obj, const MatchString &str)
    {
        return obj._word > str.s_;
    }
};

因为我认为我的“错误”有点连锁,所以我尝试尽可能详细地描述错误。

非常感谢。

【问题讨论】:

  • 首先欢迎来到 Stack Overflow。请阅读the help pages,接受SO tour,阅读How to Ask,以及this question checklist。最后,请每个问题只发布一个问题。您有多个不相关的问题。
  • 那么关于搜索,您确定排序正常吗?如果您采用更小的输入集(或者更好的是硬编码一小组字符串),排序是否能正确处理小写字母和大写字母?
  • 另外,MatchString 保存对std::string 对象的引用。当对象用于排序和匹配时,它会在整个程序中一直存在吗?请尝试创建minimal reproducible example 向我们展示。
  • 您要排序的顺序与lower_bound 期望的顺序不同。再次检查您的排序 - 它真的按字母排序吗?
  • 另外,lower_bound 想要一个排序谓词,例如“小于”,而不是相等。

标签: c++ oop vector


【解决方案1】:

首先问题是在您给定的链接中,您错误地命名了输入文件。请注意您在 main.cpp 文件中的输入文件名是 EnglishWord.txt,而您的实际输入文件名是 EnglistWord.txt。注意文件名末尾的t

第二您应该将while (reader &gt;&gt; word)替换为:

while (std::getline(reader, word))

正如我在以下正确示例中所做的那样:

#include<iostream>
#include<string>
#include<vector>
#include<fstream>
#include<sstream>
#include<algorithm>
using namespace std;
class Dictionary
{
public: 
    string _word;
public:
    string word() { return _word; }
    void getword(string value) { _word=value; }
    string display()
    {
        stringstream writer;
        writer << _word << " ";
        return writer.str();
    }
};
class FastDictionary : public Dictionary
{
public:
    void merge(std::vector<Dictionary>& list, int start, int middle, int end)
    {

        std::vector<Dictionary> left_vector(middle - start + 1);
        std::vector<Dictionary> right_vector(end - middle);
        for (int i = 0; i < left_vector.size(); ++i)
            left_vector[i] = list[start + i];
        for (int i = 0; i < right_vector.size(); ++i)
            right_vector[i] = list[middle + 1 + i];
        int left_value = 0, right_value = 0;
        int currentIndex = start;
        while (left_value < left_vector.size() && right_value < right_vector.size()) {
            if (left_vector[left_value]._word.size() <= right_vector[right_value]._word.size()) {
                list[currentIndex] = left_vector[left_value];
                left_value++;
            }
            else {
                list[currentIndex] = right_vector[right_value];
                right_value++;
            }
            currentIndex++;
        }
        while (left_value < left_vector.size()) list[currentIndex++] = left_vector[left_value++];
        while (right_value < right_vector.size()) list[currentIndex++] = right_vector[right_value++];
    }
    void mergeSort(std::vector<Dictionary>& list, int start, int end) {
        if (start < end) {
            int middle = (start + end) / 2;
            mergeSort(list, start, middle);
            mergeSort(list, middle + 1, end);
            merge(list, start, middle, end);
        }
    }
public:
    void searchmanually(vector<Dictionary> list, string value)
    {
        vector<Dictionary>::iterator it;
        it = find_if(list.begin(), list.end(), FastDictionary::MatchString(value));
        if (it != list.end())
        {
            auto idx = distance(list.begin(), it);
            cout << "Index = " << idx << endl;
        }
        else
        {
            cout << "Can not find the value !." << endl;
        }
    }
    void binary_search_find_index(vector<Dictionary> list, string value)
    {
        vector<Dictionary>::iterator it1;
        it1 = lower_bound(list.begin(), list.end(), FastDictionary::MatchString(value));
        if (it1 != list.end())
        {
            auto idx1 = distance(list.begin(), it1);
            cout << "Index = " << idx1 << endl;
        }
        else
        {
            cout << "Can not find the value !." << endl;
        }
    }
    struct MatchString
    {
    private:
        const std::string& s_;
    public:
        MatchString(const std::string& s) : s_(s) {}
        bool operator()(const Dictionary& obj) const
        {
            return obj._word == s_;
        }
        friend bool operator<(const Dictionary& obj, const MatchString &str) 
        {
            return obj._word < str.s_;
        }
        friend bool operator>(const Dictionary& obj, const MatchString &str)
        {
            return obj._word > str.s_;
        }
    };
};
    void readfile(vector<Dictionary>& list)
    {
        
        ifstream reader("EnglishWord.txt");
        string word;
        //reader.open(, ios::in);//no need for this
        if(reader)//check the state
        {
            while (std::getline(reader, word))//use getline 
            {
            
                std::cout<<word<<std::endl;
                Dictionary newList;
                newList.getword(word);
                list.push_back(newList);
            }
        }
        else 
        {
            std::cout<<"file cannot be opened"<<std::endl;
        }
        
    }
    void displayvector(vector<Dictionary>& list)
    {
        unsigned int size = list.size();
        for (int i = 0; i < size; i++)
        {
            cout << list[i].display();
        }
    }

    int main()
    {
        vector<Dictionary>list;
        FastDictionary fd;
        readfile(list);
        
        fd.mergeSort(list, 0, list.size() - 1);
        displayvector(list);
        cout << endl;
        cout << endl;
        fd.binary_search_find_index(list, "decidedly");
        cout << endl;
        fd.searchmanually(list, "decidedly");
        cout << endl;
        return 0;
    }

这个更正/修改示例的输出可以看到here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-15
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多