我有的拿着串像C++排序 - 之後的正常信件
BB
aA
12
b
AA
&
[
**
1
使用與C默認排序()一個字符串矢量特殊字符++我給這個排序列表
&
**
1
12
AA
BB
[
aA
b
取而代之的是,我需要按正常的ASCII順序排列正常字母A, a, B, b....
,其次是「特殊」字符,如0-9, *, [, , ~, !....
。
我真的不知道如何去改變矢量排序的方式,以確保它是按順序排列的。謝謝。
我有的拿着串像C++排序 - 之後的正常信件
BB
aA
12
b
AA
&
[
**
1
使用與C默認排序()一個字符串矢量特殊字符++我給這個排序列表
&
**
1
12
AA
BB
[
aA
b
取而代之的是,我需要按正常的ASCII順序排列正常字母A, a, B, b....
,其次是「特殊」字符,如0-9, *, [, , ~, !....
。
我真的不知道如何去改變矢量排序的方式,以確保它是按順序排列的。謝謝。
另一個未經測試的解決方案。
如果我錯過了的情況下,我敢肯定有人會指出來,但這裏有雲:
#include <iostream>
#include <algorithm>
#include <string>
#include <cctype>
#include <vector>
#include <iterator>
using namespace std;
int main() {
std::vector <std::string> StringVect = { "BB", "aA", "12", "b", "AA", "&", "[", "**", "1" };
std::sort(StringVect.begin(), StringVect.end(), []
(const std::string& s1, const std::string& s2)
{
if (s1.empty() || s2.empty())
return s1 < s2;
// a convenience array
bool ac[] = { isalpha(s1[0]), isalpha(s2[0]),
isdigit(s1[0]), isdigit(s2[0]),
!isalnum(s1[0]), !isalnum(s2[0]) };
// If both strings start with the same type, then return
// s1 < s2
if ((ac[0] && ac[1]) || // if both alpha strings
(ac[2] && ac[3]) || // if both digit strings
(ac[4] && ac[5])) // if both non-alphanumeric strings
return s1 < s2;
// if first string is alpha, or second string is not alphanumeric
// the strings are in order, else they are not
return (ac[0] || ac[5]);
});
copy(StringVect.begin(), StringVect.end(), ostream_iterator<string>(cout, "\n"));
}
基本上,條件這樣說:
1)字符串如果一個人被空,則返回S1 < S2
2)如果兩個字符串以相同的字符類型啓動,只返回S1 < S2
3)如果第一個字符串以字母開始,或者如果第二個字符串不是字母數字,則字符串按順序排列並返回true
,否則返回false。這裏的技巧是認識到步驟2)消除了兩個字符串的所有組合都是相同類型的,所以我們在步驟3)階段的檢查變得簡化了。
活生生的例子:http://ideone.com/jxxhIY
編輯:
如果你檢查區分大小寫的字符串,那麼你需要更改代碼,並添加不區分大小寫的檢查。我不會添加代碼,因爲有多種方法,既有各自的優缺點,也有做大小寫不敏感的比較。
#include <iostream>
#include <algorithm>
#include <string>
#include <cctype>
#include <vector>
#include <iterator>
using namespace std;
int main() {
std::vector <std::string> StringVect = { "BB", "aA", "12", "b", "AA", "&", "[", "**", "1" };
std::sort(StringVect.begin(), StringVect.end(), []
(const std::string& s1, const std::string& s2)
{
if (s1.empty() || s2.empty())
return s1 < s2;
// a convenience array
bool ac[] = { isalpha(s1[0]), isalpha(s2[0]),
isdigit(s1[0]), isdigit(s2[0]),
!isalnum(s1[0]), !isalnum(s2[0]) };
// If both strings start with the same type, then return
// s1 < s2
if ((ac[2] && ac[3]) || (ac[4] && ac[5]))
return s1 < s2;
// case insensitive
if (ac[0] && ac[1]) // both strings are alpha
return myCaseInsensitiveComp(s1, s2); //returns true if s1 < s2, false otherwise
// if first string is alpha, or second string is not alphanumeric
// the strings are in order, else they are not
return (ac[0] || ac[5]);
});
copy(StringVect.begin(), StringVect.end(), ostream_iterator<string>(cout, "\n"));
}
同樣,myCaseInsensitiveComp
是存根,你應該與實現這一目標的一個功能練習I.對於一個鏈接,看到這一點:
最近我已經瞭解,但現在它打印這個錯誤的順序'AA BB aA' – uniwolk 2015-04-02 03:27:36
所以你想基於不區分大小寫的排序嗎?你沒有在你的問題中提到這一點。 – PaulMcKenzie 2015-04-02 03:30:14
請注意,大寫字母出現在ASCII對比序列中的所有小寫字母之前,這就是您看到這種情況的原因。如果兩個字符串都以字母字符開頭,則需要添加的內容是一種比較不區分大小寫的方法。現在,它使用'std :: string'的char_traits來做比較。看到這個鏈接的替代品:http://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c – PaulMcKenzie 2015-04-02 03:55:05
您可以指定自己的函數來比較要使用的排序值。
bool myfunction(std::string a, std::string b){ ... }
std::sort(data.begin(), data.end(), myfunction);
使用myfunction
您可以指定所需的訂單。以下是有關排序的更多信息:
無論如何,你需要實現自己的比較邏輯它,並與sort
使用它。
(1)你可以給一個比較函數對象sort
,並實現自己的比較(小於)在它的邏輯,如:
struct my_comparison {
bool operator()(const string &a, const string &b) {
// implement the less than logic here
}
}
然後:
sort(v.begin(), v.end(), my_comparison());
參考:http://en.cppreference.com/w/cpp/algorithm/sort
(2)你可以實現你自己的char_traits<char>
做出特殊的string
,它使用特殊的比較兒子邏輯。如:
struct my_char_traits : public char_traits<char>
// just inherit all the other functions
// that we don't need to replace
{
static bool eq(char c1, char c2) {
// implement the comparison logic here
}
static bool lt(char c1, char c2)
// implement the comparison logic here
}
static int compare(const char* s1, const char* s2, size_t n)
// implement the comparison logic here
}
};
然後:
typedef basic_string<char, my_char_traits> my_string;
vector<my_string> v;
// ...
sort(v.begin(), v.end());
免責聲明:未經測試的代碼。
下面是一個應該工作的比較函數的實現。解決方案的關鍵是將數值重新編碼到數組中,這些數值對應於您要在比較函數中更改其順序的字符。
void initializeEncoding(char encoding[])
{
for (int i = 0; i < 256; ++i)
{
encoding[i] = i;
}
// Now re-encode for letters, numbers, and other special characters.
// The control characters end at 31. 32 == ' ', the space character.
int nextIndex = 32;
// Re-encode the uppercase letters.
for (int c = 'A'; c <= 'Z'; ++c, ++nextIndex)
{
encoding[c] = nextIndex;
}
// Re-encode the lowercase letters.
for (int c = 'a'; c <= 'z'; ++c, ++nextIndex)
{
encoding[c] = nextIndex;
}
// Re-encode the numbers.
for (int c = '0'; c <= '9'; ++c, ++nextIndex)
{
encoding[c] = nextIndex;
}
// Re-encode the special chracters.
char const* specialChars = " !\"#$%&'()*+,-./:;<=>?[\\]^_`{|}~";
for (char* cp = specialChars; *cp != '\0'; ++cp, ++nextIndex)
{
encoding[*cp] = nextIndex;
}
}
bool mycompare(char const* s1, char const* s2)
{
static char encoding[256];
static bool initialized = false;
if (!initialized)
{
initializeEncoding(encoding);
initialized = true;
}
for (; *s1 != '\0' && *s2 != '\0'; ++s1, ++s2)
{
if (encoding[*s1] != encoding[*s2])
{
break;
}
}
return ((encoding[*s1] - encoding[*s2]) < 0);
}
bool mycompare(std::string const& s1, std::string const& s2)
{
return mycompare(s1.c_str(), s2.c_str());
}
'sort'有一個可選的第三個參數 - 比較謂語。編寫你自己的,實現你想要的任何比較,傳遞給'sort'。 – 2015-04-02 02:15:54
你需要提供比較.... – Jagannath 2015-04-02 02:16:20