2014-02-20 4 views
0

Я пытаюсь написать функцию печати для набора в C++, и это то, что я писал:Проверяется текущий элемент является последним элементом множества

void print_set(set<int> &s) 
{ 
    cout<<"{"; 
    for(auto it = s.begin() ; it!=s.end() ; ++it) 
    { 
     cout<<*it; 
     if(it!=(s.end()-1)) //shows error here 
      cout<<","; 
    } 
    cout<<"}"; 
} 

Но я получаю сообщение об ошибке. Как я могу проверить, является ли текущий элемент последним элементом или нет?

+0

всегда обеспечивают полное сообщение об ошибке неизменном виде. –

+0

Вы могли бы подумать, что есть что-то вроде алгоритма 'std :: intercalate' для такого рода вещей, но я не мог найти ничего готового ... –

+0

@KarolyHorvath: Спасибо за предложение, но в этом случае, сообщение об ошибке было слишком уродливым, и я подумал, что это излишне загромождает вопрос. –

ответ

3

Могу ли я предложить альтернативный подход?

печати запятая перед тем каждый элемент, кроме первого:

void print_set(set<int> &s) 
{ 
    cout << "{"; 
    for(auto it = s.begin() ; it != s.end() ; ++it) 
    { 
     if(it != s.begin()) 
      cout << ", "; 
     cout << *it; 
    } 
    cout << "}"; 
} 
+0

Только удалили очевидную опечатку, надеюсь, что вы не возражаете –

+0

@IvayloStrandjev Нет, спасибо. – jrok

+0

Почему бы не исключить 1-й элемент из цикла? Постановка инструкции 'if' просто для пропуски 1-го элемента выглядит как-то некрасиво, по крайней мере для меня. – luk32

2

Просто проверить, равен ли следующий элемент конец:

auto next = it; 
++next; 
if (next != s.end()) 
    cout << ","; 
+2

Это приводит к увеличению его, что испортит логику цикла. –

+1

Да, соответствующий код будет 'auto next = it; ++ следующий; '. – Sneftel

+0

@MartinJ К сожалению, вы правы! –

3

set «s целые числа не являются произвольным доступом, так что вы не можете выполнять арифметические операции над ними. Вместо этого используйте std::prev.

1

На установленных итераторах можно применять только операторы ++ и --. Добавление номера не определено. Вы можете сделать свой код работать так:

void print_set(set<int> &s) 
{ 
    cout<<"{"; 
    auto second_to_last = s.end(); 
    if (!s.empty()) { 
     second_to_last--; 
    } 
    for(auto it = s.begin() ; it!=s.end() ; ++it) 
    { 
     cout<<*it; 
     if(it!=second_to_last) { 
      cout<<", "; 
     } 
    } 
    cout<<"}"; 
} 

Что делает этот код, по существу, хранить итератор на второй до последнего элемента один раз, а затем сравнить элемент, который вы имеете с ним. Обратите внимание, что second_to_last не будет точным, если набор пуст, но код будет работать, как ожидалось.

1

Что делать в этом случае:

void print_set(const std::set<int>& s) 
{ 
    const char* sep = ""; 
    std::cout << "{"; 
    for (int e : s) 
    { 
     std::cout << sep << e; 
     sep = ", "; 
    } 
    std::cout << "}"; 
} 
Смежные вопросы