сверху вниз и наоборот без цикла в С++?

Вход:

abcdE

Выход:

ABCDe

Я ищу эффективное решение с меньшим количеством кода для этого кода:

#include <iostream>   
#include <string>
using namespace std;

int main() {
    int len, ;
    string data;

    cin >> data;

    len = data.length();

    for (i = 0; i < len; i++)
        if (isupper(data[i]))
            data[i] = tolower(data[i]);
        else
            data[i] = toupper(data[i]);

    cout << data << endl;

    return 0;
}

person Riad    schedule 30.09.2016    source источник
comment
Да, есть: std::ctype::toupper(), вы можете применить это, используя std::transform() алгоритм или что-то в этом роде.   -  person πάντα ῥεῖ    schedule 30.09.2016
comment
Возможно, вы сможете написать это меньшим количеством строк, но что касается эффективности, это O (N), и, поскольку вам нужно посетить каждый элемент, насколько это возможно.   -  person NathanOliver    schedule 30.09.2016


Ответы (2)


Я полагаю, вам следует использовать std::transform:

std::string str("abcdE");
std::transform(str.begin(), str.end(), str.begin(), [](char c) {
        return isupper(c) ? tolower(c) : toupper(c);
});
person Edgar Rokjān    schedule 30.09.2016
comment
это фактически цикл, но хуже, поскольку вместо выполнения кэшированного блока кода, как оптимизированы процессоры, он выполняет анонимный вызов функции для каждого отдельного символа. Это похоже на цикл, но вместо выполнения X вы вызываете функцию на каждой итерации, которая выполняет X. Это также теряет совместимость со старыми версиями C++. Довольно высокая цена за хитрость. - person Dmitry; 27.07.2019

Вы также можете использовать std::for_each из библиотеки algorithm.

#include <iostream>   
#include <string>
#include <algorithm>

int main() {
    std::string data = "AbcDEf";
    std::for_each(data.begin(), data.end(), [](char& x){std::islower(x) ? x = std::toupper(x) : x = std::tolower(x);});
    std::cout << data<< std::endl;
}
person nishantsingh    schedule 30.09.2016
comment
Пожалуйста, не используйте магические числа для символов. C++ имеет синтаксис, позволяющий использовать вместо этого символы. - person NathanOliver; 30.09.2016
comment
@NathanOliver Я полагаю, теперь это делает тебя счастливым. - person nishantsingh; 30.09.2016
comment
Нет, но я удалю отрицательный голос. AFAIK, это все еще сломанный способ сделать это. - person NathanOliver; 30.09.2016
comment
И почему вы так себя чувствуете? - person nishantsingh; 30.09.2016
comment
Существуют и другие наборы символов, кроме ASCII, которые можно использовать для C++, и блоки букв не обязательно должны быть непрерывными. Только блок номеров гарантированно является непрерывным. - person NathanOliver; 30.09.2016
comment
Согласовано. Лучше использовать встроенные функции. - person nishantsingh; 30.09.2016