c++ 如何访问const char* 的最后一个元素

6ioyuze2  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(251)

我想把字典存储在一个列表向量中。每个列表包含所有在字母表中具有相同首字母的单词。(例如ananas,apple)我的问题是我无法将const char* 数组中以“z”开头的单词读入列表。有人能给我解释一下为什么以及如何解决这个问题吗/有没有一种方法可以用const char* 实现它?谢谢!

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

std::pair<bool, std::vector<std::list<std::string>> > loadwithList()
{
    const char* prefix = "abcdefghijklmnopqrstuvwxyz";
    std::vector<std::list<std::string>> dictionary2;

    std::ifstream infile("/Users/User/Desktop/Speller/Dictionaries/large", std::ios::in);
    if (infile.is_open())
    {
        std::list<std::string> data;
        std::string line;
        while (std::getline(infile, line))
        {
            if (line.starts_with(*prefix) && *prefix != '\0')
            {
                data.push_front(line);
            }
            else
            {
                dictionary2.push_back(data);
                data.clear();
                prefix++;
            }
        }
        infile.close();

        return std::make_pair(true, dictionary2);
    }
    std::cout << "Cant find file\n";

    return std::make_pair(false, dictionary2);

}
    int main()
    {
        auto [loaded, dictionary2] = loadwithList();
        if (!loaded) return 1;
    }
pw9qyyiw

pw9qyyiw1#

您丢失了'a'后面每个字母的第一个单词,这是因为当您到达下一个字母的单词时,if(line.starts_with(*prefix) && *prefix != '\0')失败,只有这样您才能转到下一个字母,但也会转到下一个单词。
您丢失了整个字母“z”,因为在文件的最后一行之后-if(line.starts_with(*prefix) && *prefix != '\0')在这一点上已经成功-while (std::getline(infile, line))终止,您错过了dictionary2.push_back(data);

bq9c1y66

bq9c1y662#

答案已经给出,问题也已解释。
基本上你需要一个双嵌套循环。外循环将一个字一个字地读,内循环将检查“前缀”中每个字符的mtach。这将是大量的循环。
而且效率不高,最好先用std::map来存储数据,如果你真的需要std::listsstd::vector,那么我们可以复制数据,我们会注意只存储小写字母作为std::map的键。
出于测试目的,我加载了一个包含here中单词的列表,其中大约有450'000个单词。
我在我的演示程序中使用了这个。
请参见以下一个潜在的解决方案建议:

#include <iostream>
#include <fstream>
#include <map>
#include <list>
#include <vector>
#include <utility>
#include <string>
#include <cctype>

std::pair<bool, std::vector<std::list<std::string>> > loadwithList() {
    std::vector<std::list<std::string>> data{};
    bool resultOK{};

    // Open File and check, if it could be opened
    if (std::ifstream ifs{ "r:\\words.txt" }; ifs) {

        // Here we will store the dictionary
        std::map<char, std::list<std::string>> dictionary{};

        // Fill dictionary. Read complete file and sort according to firstc character
        for (std::string line{}; std::getline(ifs, line); )

            // Store only alpha letters and words
            if (not line.empty() and std::isalpha(line.front()))

                // Use lower case start character for map. All all words starting with that character
                dictionary[std::tolower(line.front())].push_back(line);

        // Reserve space for resulting vector
        data.reserve(dictionary.size());

        // Move result to vector
        for (auto& [letter, words] : dictionary)
            data.push_back(std::move(words));

        // All good
        resultOK = true;
    }
    else
        std::cerr << "\n\n*** Error: Could not open source file\n\n";

    // And give back the result
    return { resultOK , data };
}
int main() {
    auto [result, data] = loadwithList();

    if ( result) 
        for (const std::list<std::string>&wordList : data) 
            std::cout << (char)std::tolower(wordList.front().front()) << " has " << wordList.size() << "\twords\n";
}

相关问题