c++处理开销

C++ Processing Hog

本文关键字:开销 处理 c++      更新时间:2023-10-16

我对c++非常陌生(对编程并不陌生),并且一直在处理Google Code Jam问题。我用Python(我最有经验的语言)和c++按照相同的算法正确地解决了这个问题(异形语言)。根据我的经验,c++比python要快得多,原因很明显;然而,我的python版本执行速度比我的c++版本快100倍。加工是限制因素。很明显我做错了什么,只是不知道是什么。在采取更详细的措施来找到资源消耗者之前,我想我应该在这里问一下,因为这似乎是一个非常简单的解决方案,让有c++经验的人指出我代码中的资源或方法效率低下。我正在运行unix环境。

我将把我的c++代码贴在下面。如果有人认为看到我的python代码可以帮助他们回答我的问题,我也很乐意把它贴出来。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main () 
{
    int L, D, N;
    std::cin >> L;
    std::cin >> D;
    std::cin >> N;
    std::cin.ignore();
    std::string dictionary [D];
    for (int i=0; i<D; i++) {
        std::getline(std::cin, dictionary[i]);
    }   
    for (int tt=1; tt<=N; tt++) {
        std::cerr << tt << std::endl;
        std::string case_word;
        std::getline(std::cin, case_word);
        int current_letter = 0;
        std::vector <int> invalid_indexes;
        while (case_word.length() > 0) {
            std::vector <char> required_letters;
            if (case_word[0] != '(') {
                required_letters.push_back(case_word[0]);
                case_word.erase(case_word.begin());
            }   
            else {
                std::string::iterator closing_parenthesis = std::find(case_word.begin(), case_word.end(), ')');
                std::string::iterator p = case_word.begin()+1;
                while (p != closing_parenthesis) {
                    required_letters.push_back(*(p++));
                }   
                case_word.erase(case_word.begin(), closing_parenthesis+1);
            }   
            for (int dictionary_word=0; dictionary_word<D; dictionary_word++) {
                if (std::find(invalid_indexes.begin(), invalid_indexes.end(), dictionary_word) != invalid_indexes.end()) {
                    continue;                         
                }   
                if (std::find(required_letters.begin(), required_letters.end(), dictionary[dictionary_word][current_letter]) == required_letters.end()) {
                    invalid_indexes.push_back(dictionary_word);
                }   
            }   
            current_letter++;
        }
        std::cout << "Case #" << tt << ": " << D - invalid_indexes.size() << std::endl;
    }
return 0;
}

这是我对你的代码的理解。可能有一些花哨的DFA可以从字典中构建,以完全加快算法的速度。这只是尝试用更好的数据结构来加速你的算法。

for (int tt=1; tt<=N; tt++) {
    std::cerr << tt << std::endl;
    std::string case_word;
    std::getline(std::cin, case_word);
    int current_letter = 0;
    std::string::iterator i = case_word.begin();

将代码切换到迭代case_word,以避免从前面擦除数据的开销。

    std::tr1::unordered_set<int> invalid_indexes(D);
    while (i != case_word.end()) {
        std::tr1::unordered_set<char> required_letters(256);

使用无序集合以获得更高效的索引查找。(tr1命名空间是因为我编译时没有启用c++ 11)。

        if (*i != '(') {
            required_letters.insert(*i);
            ++i;
        }
        else {
            std::string::iterator closing_parenthesis
                = std::find(i, case_word.end(), ')');
            std::string::iterator p = i+1;
            while (p != closing_parenthesis) {
                required_letters.insert(*(p++));
            }
            i = closing_parenthesis+1;
        }
        for (int dictionary_word=0; dictionary_word<D; dictionary_word++) {
            int index = dictionary_word;
            if (invalid_indexes.find(index) != invalid_indexes.end()) {
                continue;
            }
            char letter = dictionary[index][current_letter];
            if (required_letters.find(letter) == required_letters.end()) {
                invalid_indexes.insert(dictionary_word);
            }

注意使用unordered_set所得到的简化(和更快)的搜索。

        }
        current_letter++;
    }
    std::cout << "Case #" << tt
              << ": " << D - invalid_indexes.size()
              << std::endl;
}