我正在解决String Array的排序非冗余排列问题。
例如,如果输入字符串是"8aC"
,那么输出应该是{"Ca8","C8a", "aC8", "a8C", "8Ca", "9aC"}
的顺序。我选择了C ++数据结构集,因为每次我将String插入std:set时,set都会自动排序并消除冗余。输出很好。
但是我想在不同的字母数字排序中排序设置,这与默认的字母数字排序顺序不同。我想自定义设置顺序优先级的比较器,如:upper case> lower case > digit
。
我试图自定义比较器但是非常令人沮丧。 如何自定义集合的排序顺序?这是我的代码。
set<string, StringCompare> setl;
for (i = 0; i < f; i++)
{
setl.insert(p[i]); //p is String Array. it has the information of permutation of String.
}
for (set<string>::iterator iter = setl.begin(); iter != setl.end(); ++iter)
cout << *iter << endl; //printing set items. it works fine.
struct StringCompare
{
bool operator () (const std::string s_left, const std::string s_right)
{
/*I want to use my character comparison function in here, but have no idea about that.
I'm not sure about that this is the right way to customize comparator either.*/
}
};
int compare_char(const char x, const char y)
{
if (char_type(x) == char_type(y))
{
return ( (int) x < (int) y) ? 1 : 0 ;
}
else return (char_type(x) > char_type(y)) ? 1 : 0;
}
int char_type(const char x)
{
int ascii = (int)x;
if (ascii >= 48 && ascii <= 57) // digit
{
return 1;
}
else if (ascii >= 97 && ascii <= 122) // lowercase
{
return 2;
}
else if (ascii >= 48 && ascii <= 57) // uppercase
{
return 3;
}
else
{
return 0;
}
}
答案 0 :(得分:1)
你的比较器是对的。我会像这样将参数转换为const ref
bool operator () (const std::string &s_left, const std::string &s_right)
从这个简单的实现开始:
return s_left < s_right
这将提供默认行为,让您确信自己走在正确的轨道上。 然后开始比较当时的一个字符和两个字符串长度之间的较短的for循环。您可以使用operator [](例如s_left [i])
简单地删除字符串答案 1 :(得分:1)
你几乎就在那里,但你应该按字典顺序比较你的字符串。 我粗略地为你的代码添加了一些小改动。
int char_type( const char x )
{
if ( isupper( x ) )
{
// upper case has the highest priority
return 0;
}
if ( islower( x ) )
{
return 1;
}
if ( isdigit( x ) )
{
// digit has the lowest priority
return 2;
}
// something else
return 3;
}
bool compare_char( const char x, const char y )
{
if ( char_type( x ) == char_type( y ) )
{
// same type so that we are going to compare characters
return ( x < y );
}
else
{
// different types
return char_type( x ) < char_type( y );
}
}
struct StringCompare
{
bool operator () ( const std::string& s_left, const std::string& s_right )
{
std::string::const_iterator iteLeft = s_left.begin();
std::string::const_iterator iteRight = s_right.begin();
// we are going to compare each character in strings
while ( iteLeft != s_left.end() && iteRight != s_right.end() )
{
if ( compare_char( *iteLeft, *iteRight ) )
{
return true;
}
if ( compare_char( *iteRight, *iteLeft ) )
{
return false;
}
++iteLeft;
++iteRight;
}
// either of strings reached the end.
if ( s_left.length() < s_right.length() )
{
return true;
}
// otherwise.
return false;
}
};
答案 2 :(得分:0)
你已经拥有了你所拥有的东西。
在您的比较仿函数中,您将获得两个std::string
个。你需要做的是找到两个字符串不同的第一个位置。为此,您可以使用标准库中的std::mismatch
。这将返回一个std::pair
,其中填充了指向前两个不同元素的迭代器:
auto iterators = std::mismatch(std::begin(s_left), std::end(s_left),
std::begin(s_right), std::end(s_right));
现在,您可以取消引用我们获得字符的两个迭代器:
char c_left = *iterators.first;
char c_right = *iterators.second;
您可以将这两个字符传递给compare_char
函数,它应该全部有效: - )
答案 3 :(得分:0)
对此没有绝对的肯定,但是你可以使用枚举类来获得你的优势或数组,并选择从某些你喜欢的订单中读取。
您可以使用一个枚举类来定义要输出数据的顺序,另一个包含要输出的数据,然后您可以设置一个循环,继续循环以将值分配给输出中的值方式!
namespace CustomeType
{
enum Outs { Ca8= 0,C8a, aC8, a8C, 8Ca, 9aC };
enum Order{1 = 0 , 2, 3 , 4 , 5};
void PlayCard(Outs input)
{
if (input == Ca8) // Enumerator is visible without qualification
{
string[] permuted;
permuted[0] = Outs[0];
permuted[1] = Outs[1];
permuted[2] = Outs[2];
permuted[3] = Outs[3];
permuted[4] = Outs[4];
}// else use a different order
else if (input == Ca8) // this might be much better
{
string[] permuted;
for(int i = 0; i<LessThanOutputLength; i++)
{
//use order 1 to assign values from Outs
}
}
}
}
答案 4 :(得分:0)
这应该有效:
bool operator () (const std::string s_left, const std::string s_right)
{
for(int i = 0;i < s_left.size();i++){
if(isupper(s_left[i])){
if(isupper(s_right[i])) return s_left[i] < s_right[i];
else if(islower(s_right[i]) || isdigit(s_right[i]))return true;
}
else if(islower(s_left[i])){
if(islower(s_right[i])) return s_left[i] < s_right[i];
else if(isdigit(s_right[i])) return true;
else if(isupper(s_right[i])) return false;
}
else if(isdigit(s_left[i])){
if(isdigit(s_right[i])) return s_left[i] < s_right[i];
else if(islower(s_right[i]) || isupper(s_right[i])) return false;
}
}
}