2016-10-03 20 views
4

C++で、大文字が小文字に先行するようにアルファベット順にソートするプログラムを作成しようとしていました。 例: DCBAdcba ソート文字列: AABBCCDD大文字アルファベット順に文字列を配置するC++

は、下記のコードです。

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

char_構造体は、大文字(0又は32、元の文字は、それぞれ、小文字または大文字であった場合に応じて)から個々の文字(小文字に換算)とそれらの差を格納するために作成されます。次に、小文字の値に基づいてchar_文字をソートします。そして、ソートの後に、大文字のフォームを取り出すために差を文字に追加します。

しかし、この文字列を入力しようとすると、次の結果が得られます。

DCBAdcba

AABBCCDD

私はここで何が起こっているかを理解することはできません。

+1

デバッガを使用してコードをステップ実行する方法を学ぶ必要があるようです。良いデバッガを使用すると、プログラムを1行ずつ実行し、どこからずれているかを確認することができます。これはプログラミングをする場合に不可欠なツールです。さらに読む:** [小さなプログラムをデバッグする方法](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)** – NathanOliver

+2

大文字と小文字を区別しないソートアルゴリズムを作成しました。私は大文字を優先するコードは見当たりません。 –

+0

ヒント - 「Ascii table」を検索し、各文字に割り当てられた値を確認します。 – UKMonkey

答えて

4

問題は、この行にある:

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; 
} 
0

std::stringコンテナcharのSとして、そのように考えることができますSTLのアルゴリズムをそのコンテンツに適用することができますたとえば、(STLアルゴリズムを、 std::vector)。

あなたは、例えば、std::sort()の三番目の引数として渡すことが、ラムダを使用して、特定のカスタムソート条件を指定することができます(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'; 
} 
関連する問題