Coroutine demo source

后端 未结 3 1036
盖世英雄少女心
盖世英雄少女心 2021-01-07 02:54

Here\'s an example of a program, where coroutines really help to simplify the algorithm - imho its hardly possible to implement otherwise. I also tried to choose a useful ta

3条回答
  •  北海茫月
    2021-01-07 03:33

    Just for grins, here's a rough idea of how I'd handle the part that just encodes to/decodes from an arbitrary alphabet. As promised, the actual encoding/decoding is around a dozen lines of code. The overall size is larger, largely because I've used templates throughout, so the numbers can be an arbitrary integer type, and the characters can be an arbitrary character type, and it uses iterators for both, so it can read from/write to arbitrary collections (streams, stringstreams, vectors, etc.)

    Edit: modified code to read input from a file and write output to a file (and fixed a minor error or two):

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    template 
    intT log2(intT input) { 
        return intT(log10((double)input) / log10(2.0));
    }
    
    template 
    class coder { 
        std::string alphabet;   
        size_t range;
        unsigned ratio;
    public:
        coder(std::string const &alpha) : alphabet(alpha), range(alpha.size()) {
            ratio = ceil(double(log2(std::numeric_limits::max())/log2(range)));
        }
    
        template 
        void encode(inIt begin, inIt end, outIt out) { 
            while (begin != end) {
                intT val = *begin++;
                for (int i=0; i
        void decode(inIt begin, inIt end, outIt out) { 
            while (begin != end) {
                int temp = 0;
                for (int i=0; i \n";
            return EXIT_FAILURE;
        }
    
        coder enc("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        std::ifstream in(argv[1], std::ios::binary);
        std::ofstream out(argv[2]);
        clock_t start = clock();
        enc.encode(std::istream_iterator(in), 
            std::istream_iterator(), 
            std::ostream_iterator(out, ""));
        clock_t stop = clock();
        std::cerr << "Processing time: " << double(stop-start)/CLOCKS_PER_SEC << "\n";
        return 0;
    }
    

    At least for the moment, I've ignored the arithmetic encoding part, but it should (at least IMO) follow a similar structure so you could pretty easily string things together more or less arbitrarily.

    As far as comparing speed and size goes, keep in mind that this isn't doing any compression (at all) just the baseX encoding -- that being the case, attempting to compare to something that does compression makes no real sense (except, for example, to get an idea of how effective the compression is -- but if it's effective at all, it'll obviously produce smaller output).

    As far as executable size goes, about all I can say is that gcc producing large executables never surprises me. Using MS VC++, I get an executable of 9,728 bytes for the code above.

提交回复
热议问题