Чтение и анализ строки в C / C ++; положить токены в массив или вектор или аналогичную структуру - PullRequest
1 голос
/ 17 февраля 2010

Мне нужно отправить код для одной из проблем в ACM IPC, и, как вы, наверное, знаете, время имеет большое значение. Итак, я должен эффективно читать ввод, как это: Первая строка будет содержать последовательность целочисленных значений, а вторая строка будет содержать последовательность целочисленных значений, связанных с другой последовательностью. E.g.:

3 2 1 4 5 7 6    
3 1 2 5 6 7 4   
7 8 11 3 5 16 12 18   
8 3 11 7 16 18 12 5   
255  
255

Я должен поместить первую строку в массив, а вторую - в другую и передать обе функции.

Как мне прочитать и поместить их в C / C ++? Я думал по-C, но мой подход будет иметь 2 время ... Я предпочитаю читать с помощью scanf, но синтаксический анализ можно выполнять, как вы хотите.

Пожалуйста, помогите этому новичку!

Ответы [ 3 ]

3 голосов
/ 17 февраля 2010

Считайте строки, используя std::getline(). Затем используйте std::stringstream для разбора каждой строки. Так как это для соревнования, вам не нужен настоящий код.

1 голос
/ 17 февраля 2010
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>

typedef std::vector< int > ints_t;

void dump_ints( const ints_t& input )
{
    std::copy(
        input.begin(),
        input.end(),
        std::ostream_iterator< int >( std::cout, " " ) );
    std::cout << std::endl;
}

void foo( const ints_t& first, const ints_t& second )
{
    dump_ints( first );
    dump_ints( second );
}

bool parse_line( std::istream& is, ints_t* output )
{
    std::string line;
    if ( std::getline( is, line ) )
    {
        std::istringstream raw_ints( line );
        std::copy(
            std::istream_iterator< int >( raw_ints ),
            std::istream_iterator< int >(),
            std::back_inserter( *output ) );
        return true;
    }
    else
    {
        return false;
    }
}

bool parse( std::istream& is, ints_t* first, ints_t* second )
{
    const bool result = parse_line( is, first ) && parse_line( is, second );
    return result;
}

void run( std::istream& is )
{
    while ( is )
    {
        ints_t first;
        ints_t second;
        if ( parse( is, &first, &second ) )
        {
            foo( first, second );
        }
    }
}

int main()
{
    //if you want to read input from file use ifstream and comment istringstream 
//    std::ifstream is( "put_here_a_path_to_input_file" );
    std::istringstream is( 
        "3 2 1 4 5 7 6\n"
        "3 1 2 5 6 7 4\n"
        "7 8 11 3 5 16 12 18\n"
        "8 3 11 7 16 18 12 5\n"
        "255\n"
        "255\n" 
        );
    run( is );
}
0 голосов
/ 17 февраля 2010

Вы также можете использовать strtok () и strdup ().

См. пример использования strtok () и strdup () .Затем strtok () будет использоваться для извлечения отдельных токенов - strdup () для выделения места для их копирования.

...