简体   繁体   English

以大写第一字母顺序C ++排列字符串

[英]Arranging a string in uppercase-first alphabetical order C++

I was trying to create a program in C++ that sorts a given string in alphabetical order in a way where the uppercase letters precede their lowercase equivalent. 我试图用C ++创建一个程序,按照字母顺序对给定字符串进行排序,其方式是大写字母在它们的小写等价物之前。 Example: DCBAdcba Sorted string: AaBbCcDd 示例:DCBAdcba已排序字符串:AaBbCcDd

Given 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 is created to store the individual characters(converted to to lowercase) and their difference from the uppercase equivalent(0 or 32, depending if the original char was lowercase or uppercase, respectively). 创建char_ struct以存储单个字符(转换为小写)以及它们与大写等效项的区别(0或32,具体取决于原始字符分别是小写字母还是大写字母)。 It then sorts the char_ characters on the basis of their lowercase values. 然后它根据它们的小写值对char_字符进行排序。 And after the sort we add back the difference to the character to retrieve the uppercase form. 在排序之后,我们将差异添加回字符以检索大写形式。

But when I try giving this string, it gives the following result. 但是当我尝试给出这个字符串时,它给出了以下结果。

DCBAdcba DCBAdcba

AabBCcdD AABBCCDD

I cannot understand what's happening here. 我无法理解这里发生了什么。

The problem is on this line: 问题出在这一行:

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

It compares characters in case-insensitive way, with no provision for tie breaking when lowercase characters are the same. 它以不区分大小写的方式比较字符,当小写字符相同时没有提供打破平局的规定。

You need to modify this to swap characters when lowercase on the right is greater than lowercase on the left, or when lowercase representations are the same, but the right side original character is in upper case: 如果右侧的小写大于左侧的小写,或者小写表示相同,但​​右侧原始字符为大写,则需要修改此项以交换字符:

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

sorts a given string in alphabetical order in a way where the uppercase letters precede their lowercase equivalent. 按字母顺序对给定字符串进行排序,其方式是大写字母位于其小写等效字母之前。

You can just define a comparison functor reflecting your intention 您可以定义一个反映您意图的比较仿函数

#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);
    }
};

Then use std::sort : 然后使用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;
}

std::string can be considered as a container of char s, and as such you can apply STL's algorithms to its content, including std::sort() (just like you would apply an STL algorithm to eg std::vector ). std::string可以被视为char容器 ,因此你可以将STL的算法应用于其内容,包括std::sort() (就像你将STL算法应用于例如std::vector )。

You can specify your particular custom sorting criteria using a lambda , to be passed as the third parameter to std::sort() , eg ( live on Ideone ): 您可以使用lambda指定特定的自定义排序条件 ,作为第三个参数传递给std::sort() ,例如( 在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';
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM