1

Input:

abcdE

Output:

ABCDe

I am looking for an efficient and less code solution for this code:

#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;
}
Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
  • 2
    Yeah, there is: [`std::ctype::toupper()`](http://en.cppreference.com/w/cpp/locale/ctype/toupper), you may apply that using a `std::transform()` algo or such. – πάντα ῥεῖ Sep 30 '16 at 19:17
  • You might be able to write this in fewer lines but as for efficient this is O(N) and since you have to visit every element that as good as you can get. – NathanOliver Sep 30 '16 at 19:19

2 Answers2

2

I suppose you should use std::transform:

std::string str("abcdE");
std::transform(str.begin(), str.end(), str.begin(), [](char c) {
        return isupper(c) ? tolower(c) : toupper(c);
});
Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
  • thats effectively a loop, but worse since instead of performing a cached block of code the way cpus are optimized, it performs an anonymous function call on every single character. It's like a loop but instead of doing X, you are calling a function on each iteration that does X. It also loses compatibility with older c++ versions. Quite a hefty price for cleverness. – Dmytro Jul 27 '19 at 02:49
0

You can also use std::for_each from algorithm library.

#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;
}
nishantsingh
  • 4,537
  • 5
  • 25
  • 51