Organizing a string in uppercase-first alphabetical order C ++

I tried to create a C ++ program that sorts a given string in alphabetical order so that capital letters precede their lowercase equivalent. Example: DCBAdcba Sorted String: AaBbCcDd

Below is the code.

#include <iostream>
#include <string>
#include <cctype>
struct char_ {
    char c;
    char diff;
    char_();
    char_(char x);
};
char_::char_() {
    c = 0;
    diff = 0;
}
char_::char_(char x) {
    c = std::tolower(x);
    diff = c - x;
}

void charswap(char_& x, char_& y) {
    char_ temp;
    temp = x;
    x = y;
    y = temp;
}

int main() {
    std::string str;
    getline(std::cin, str);
    char_* str2 = new char_[str.length()];
    for (int i = 0; i < str.length(); i++) {
        str2[i] = char_(str[i]);
    }

    /*
    for (int i = 0; i < str.length(); i++) {
        std::cout << str2[i].c << std::endl;
    }
    */
    for (int i = 0; i < str.length(); i++) {
        for (int j = i; j < str.length(); j++) {
            if (str2[i].c > str2[j].c)
                charswap(str2[i], str2[j]);
        }
    }


    for (int k = 0; k < str.length(); k++) {
    std::cout << str2[k].c << "\t" << (int)str2[k].diff << std::endl;
    }

    for (int i = 0; i < str.length(); i++) {

    str2[i].c = str2[i].c - str2[i].diff;
    }




    for (int i = 0; i < str.length(); i++) std::cout << str2[i].c;
    std::cout << "\n";
    return 0;
}

A char_ struct structure has been created for storing individual characters (converted to lowercase) and their difference from the upper case equivalent (0 or 32, depending on whether the original char was lowercase or uppercase, respectively). Then it sorts char_ characters based on their string values. And after sorting, we will add the difference to the character to get the form in upper case.

But when I try to give this line, it gives the following result.

DCBAdcba

AabBCcdd

I can not understand what is happening here.

+4
3

:

if (str2[i].c > str2[j].c)
    charswap(str2[i], str2[j]);

, , .

, , , , :

if ((str2[i].c > str2[j].c) || (str2[i].c == str2[j].c && str2[j].diff))
    charswap(str2[i], str2[j]);
+4

, .

,

#include <cctype>
#include <iostream>
#include <vector>
#include <algorithm>

struct case_cmp {
    bool operator()(char lhs, char rhs) const {
        return (std::isupper(lhs) && std::tolower(lhs) == rhs) || std::tolower(lhs) < std::tolower(rhs);
    }
};

std::sort:

int main() {
    std::string s("DCBAdcba");
    std::sort(std::begin(s), std::end(s), case_cmp());
    // Outputs "AaBbCcDd"
    std::cout << s << std::endl;
}
+4

std::string char s, STL , std::sort() ( , STL , std::vector).

You can specify specific custom sorting criteria using lambdas, which will be passed as the third parameter to std::sort(), for example. ( live on Ideone ):

#include <algorithm>    // for std::sort
#include <cctype>       // for std::isupper, std::tolower
#include <iostream>     // for std::cout
#include <string>       // for std::string
using namespace std;

int main() {
    string s{"DCBAdcba"};

    sort( s.begin(), s.end(), [](char x, char y) { 
        // Custom sorting criteria.
        // Return true if x precedes y.

        // This may work, but requires more testing...
        if (isupper(x)) {
            if (tolower(x) == y) {
                return true;    
            }   
        }
        return tolower(x) < tolower(y);
    });

    cout << s << '\n';
}
0
source

Source: https://habr.com/ru/post/1656596/


All Articles