Эквивалент итератора Java в C ? (с кодом)

#java #c

#java #c

Вопрос:

Привет всем. Друг написал для меня некоторый Java-код, и я легко могу преобразовать его в C , но мне очень любопытно, как найти эквивалент для Java-итератора на C . Вот код, и я, скорее всего, хотел бы, чтобы данные возвращались в вектор. Любая помощь приветствуется

 public class RLEIterator
extends RegionIterator
{
    public int reg = 0;
    public int mode = 0;
    public int skip = 0;
        // mode is the number of IDs that are valid still (count down)
        // skip is used after we run out of mode IDs, and move forward
        //   The goal is, to always have a valid 'hasNext' state, after
        // an ID is read via 'next'. Thus, the initial search, and then
        // the reading forward if mode == 0, after the ID is found.
    public int i;

    public RLEIterator()
    {
        // Need to set up the skip of an initial part, so we can
        // correctly handle there not being anything, despite there
        // being data encoded.

        int comp;
        i = 0;

        while ((mode == 0) amp;amp; (i<nearRLE.length))
        {
            // set up the next code
            comp = ((int)nearRLE[i]) amp; 0xff;

            if ((comp > 0) amp;amp; (comp <= 0x3e))
            {
                // skip forward by comp;
                reg  = comp;
                i  ;
                mode = 0; // have to keep on reading
            }
            else if (comp == 0x3f)
            {
                // skip forward by the following 16 bit word;
                // second byte is hi-byte of the word
                reg  = ((int)nearRLE[i 1]) amp; 0xff;
                reg  = (((int)nearRLE[i 2]) amp; 0xff) << 8;

                i =3;
            }
            else if (comp == 0xff)
            {
                // include the following WORD of regions
                mode = ((int)nearRLE[i 1]) amp; 0xff;
                mode  = (((int)nearRLE[i 2]) amp; 0xff) << 8;
                i  = 3;
            }
            else if ((comp >= 0xc0) amp;amp; (comp <= 0xfe))
            {
                // comp - 0xc0 regions are nearby
                mode = comp - 0xc0;  //  1 perhaps?
                i  ;
            }
            else if ((comp >= 0x40) amp;amp; (comp <= 0x7f))
            {
                // skip bits 3-5 IDs and then include bits 0-2
                reg  = (comp amp; 0x38) >> 3;
                mode = (comp amp; 0x7);
                i  ;
            }
            else if ((comp >= 0x80) amp;amp; (comp <= 0xbf))
            {
                // include IDs bits 3-5, then skip bits 0-2
                mode = (comp amp; 0x38) >> 3;
                skip = (comp amp; 0x7);
                i  ;
            }
        }
    }

    public boolean hasNext()
    {
        // not at the end of the RLE, and not currently processing a
        // directive. (mode)
        return (mode > 0);
    }

    public int next()
    {
        int ret = -1;
        int comp;

        // sanity check first. Shouldn't truthfully get called if mode
        // isn't >0
        if (mode <= 0)
            return -1;

        ret = reg;
        reg  ;
        mode--;

        if (mode == 0)
        {
            // skip forward
            reg  = skip;
            skip = 0;

            while ((mode == 0) amp;amp; (i<nearRLE.length))
            {
                // set up the next code
                comp = ((int)nearRLE[i]) amp; 0xff;

                if ((comp > 0) amp;amp; (comp <= 0x3e))
                {
                    // skip forward by comp;
                    reg  = comp;
                    i  ;
                    mode = 0; // have to keep on reading
                }
                else if (comp == 0x3f)
                {
                    // skip forward by the following 16 bit word;
                    // second byte is hi-byte of the word
                    reg  = ((int)nearRLE[i 1]) amp; 0xff;
                    reg  = (((int)nearRLE[i 2]) amp; 0xff) << 8;

                    i =3;
                }
                else if (comp == 0xff)
                {
                    // include the following WORD of regions
                    mode = ((int)nearRLE[i 1]) amp; 0xff;
                    mode  = (((int)nearRLE[i 2]) amp; 0xff) << 8;
                    i  = 3;
                }
                else if ((comp >= 0xc0) amp;amp; (comp <= 0xfe))
                {
                    // comp - 0xc0 regions are nearby
                    mode = comp - 0xc0;  //  1 perhaps?
                    i  ;
                }
                else if ((comp >= 0x40) amp;amp; (comp <= 0x7f))
                {
                    // skip bits 3-5 IDs and then include bits 0-2
                    reg  = (comp amp; 0x38) >> 3;
                    mode = (comp amp; 0x7);
                    i  ;
                }
                else if ((comp >= 0x80) amp;amp; (comp <= 0xbf))
                {
                    // include IDs bits 3-5, then skip bits 0-2
                    mode = (comp amp; 0x38) >> 3;
                    skip = (comp amp; 0x7);
                    i  ;
                }
            }
        }

        return ret;
    }
}
  

Опять же, любая помощь о том, как это будет вписываться в схему одной функции (если возможно) в C , была бы фантастической. Спасибо!

Комментарии:

1. C ест на завтрак то, что Java (и Python, C # и, возможно, несколько других) ребята называют итератором.

2. @delnan, В этом случае было бы легко предоставить впечатляющий ответ. 😉 Стоит добавить, что это не итератор.

3. @delnan Да. Хотелось бы увидеть пример 🙂

4. К сожалению, я не опытный гуру C , поэтому нам придется подождать, пока кто-нибудь другой покажет код. Я могу просто сказать вам, что C содержит множество различных и полезных итераторов, в отличие от упрощенных «итераторов» других языков, предназначенных только для прямой передачи. Если возникнет необходимость, версия C могла бы с успехом выполнять лунную прогулку и жонглировать бензопилами при этом, и половина алгоритмов STL работала бы с этим.

5. Место, где вы используете итераторы в C , — это использование контейнеров STL. Похоже на Java, т. е. hashmap и прочее.

Ответ №1:

Насколько вы знакомы с итераторами C ? Они разработаны так, чтобы выглядеть очень похоже на указатели, так что, учитывая итератор it :

   it
  

увеличит итератор (перейдет к следующему элементу)

 *it
  

разыменует ли итератор (вернет ссылку на элемент, на который он указывает)

 --it
  

уменьшит ли (если он вообще определен) итератор (вернется к предыдущему элементу)

Итераторы C , как правило, ничего не знают о контейнере, с которым они работают. В частности, способ проверить, осталось ли в последовательности больше элементов, заключается не в вызове HasNext итератора, а в сравнении его с итератором, который, как вы знаете, указывает на конец последовательности. (или, строго говоря, сравните его с элементом, который указывает сразу за концом последовательности.)

Помимо этого, итераторам необходимо определить несколько typedefs и другие вспомогательные элементы, чтобы помочь компилятору классифицировать и понять возможности итератора.

Самый простой способ определить итератор — использовать Boost. iterator_facade Класс библиотеки итераторов, который реализует почти все необходимые функции для вас. Библиотека имеет отличную документацию, включая руководство, описывающее, как определить свой собственный тип итератора.

Если использование Boost — это вариант, вы определенно должны пойти на это. В противном случае, в стандартной библиотеке есть std::iterator , которая также немного помогает (но, стоит отметить, не обязательна — итераторы могут быть определены совершенно корректно, не производя от этого класса)

Мне жаль, что у меня нет полного примера, но сейчас я немного спешу. (И, если вы можете использовать Boost, было бы пустой тратой времени заниматься определением примера итератора с нуля). Надеюсь, вышесказанного достаточно, чтобы вы начали.