在c++中按非ascii顺序的首字母对字符串向量进行排序
Sorting a vector of strings by the first letter in non-ascii order in C++
我有一个包含单词列表的文本文件。
我使用ifstream
将这些单词读入vector
,现在我正试图以类似的顺序对它们进行排序:
A a B b C c [...]
我尝试使用气泡搜索算法中的第三个for循环来实现这一点,以查看每个单词的第一个字符(我知道这远远不是最有效的方法,特别是如果我使用的是大型数据集)
然后检查该字母和下一个字母是大写还是小写,如果大写字母与当前字母相同,则切换,但这似乎不起作用。
void bubble_Sort (vector <string> & words)
{
for (unsigned i = words.size(); i >= 2; --i)
{
for (unsigned k = 0; k + 1 < i; k++)
{
int hi = k+1;
string temp1 = words[hi];
string temp2 = words[k];
int smallsize = words[hi].size();
int smallprecedence = 0;
if (words[k].size() < words[hi].size())
smallsize = words[k].size();
for (unsigned j = 0; j < smallsize; j++)
{
if (temp1[j] >= 'A' && temp1[j] <= 'Z')
{
if (temp2[j] >='a' && temp2[j] <= 'z')
{
char lowercase1 = temp1[j] + 32;
if (lowercase1 == temp2[j])
{
string temp = words[k];
words[k] = words[hi];
words[hi] = temp;
break;
}
}
else if (temp2[j] >= 'A' && temp2[j] <= 'Z')
{
if (temp1[j] < temp2[j])
{
string temp = words[k];
words[k] = words[hi];
words[hi] = temp;
break;
}
}
}
if (temp1[j] >= 'a' && temp1[j] <= 'z')
{
if (temp2[j] >= 'A' && temp2[j] <= 'Z')
{
char uppercase1 = temp1[j] - 32;
if (uppercase1 < temp2[j])
{
string temp = words[k];
words[k] = words[hi];
words[hi] = temp;
break;
}
}
else if (temp2[j] >= 'a' && temp2[j] <= 'z')
{
if (temp1[j] < temp2[j])
{
string temp = words[k];
words[k] = words[hi];
words[hi] = temp;
break;
}
}
}
else if (temp1[j] == temp2[j] && temp1.size() < temp2.size())
++smallprecedence;
}
if (smallprecedence == smallsize)
{
string temporary = words[k];
words[k] = words[hi];
words[hi] = temporary;
}
}
}
}
别白费力气了。只需修改默认的比较函数aA <bB(不论情况)和A><一。>
我使用了错误的比较函数。它应该为<
返回true
,为>=
返回false
。
std::vector<std::string> vec;
//
std::sort(vec.begin(), vec.end(), [](const std::string& lhs, const std::string& rhs)
{
const char* s1=lhs.c_str();
const char* s2=rhs.c_str();
while(true) {
// first ignore case
if ( std::toupper(*s1) < std::toupper(*s2) ) return true;
if ( std::toupper(*s1) > std::toupper(*s2) ) return false;
// end of both strings, exact match
if ( *s1 == 0 && *s2 == 0 ) return false;
// compare upper case vs lower case ('A' vs 'a')
if ( *s1 > *s2) return false;
if ( *s1 < *s2) return true;
++s1; ++s2;
}
});
首先,去掉硬编码的ascii。很早以前,C和c++就有函数来确定一个字符是字母、数字、大写还是小写等等。查一下。
第二,清楚地描述是什么决定了你想要的结果的顺序。
第三,根据上述描述,编写一个函数,它接受两个字符串,并告诉您第一个字符串是否应该出现在第二个字符串之前。在排序中使用函数您可以使用std::sort
对矢量进行排序,并使用std::string::at()
:
std::string
中第一个字符的引用。std::vector<std::string> vec;
//
std::sort(vec.begin(), vec.end(), [](const std::string& lhs, const std::string& rhs)
{
char l_ch, r_ch;
l_ch = lhs.at(0);
r_ch = rhs.at(0);
return l_ch < r_ch;
});
我认为跳过完全相等的前缀,然后用大写字母比较一次就足够了:
std::vector<std::string> vec;
//
std::sort(vec.begin(), vec.end(), [](const std::string& lhs, const std::string& rhs)
{
const char* s1=lhs.c_str();
const char* s2=rhs.c_str();
while(*s1 && *s1 == *s2) {++s1; ++s2;}
int rc = toupper(*s1) - toupper(*s2);
if (rc) return rc;
return *s1 - *s2;
});
如果您只需要比较首字母,只需删除while(*s1 && *s1 == *s2) {++s1; ++s2;}
相关文章:
- 在 C++11 中,如何查找并返回以给定字符串开头的字符串向量中的所有项?
- 在将字符串放入字符串向量时遇到问题?
- 如何从字符串向量构造对象并避免复制?
- 如何在目录及其子文件夹中构建文件名字符串向量?
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 将字符串向量中的字符串放入主字符串中
- 如何在 c++ 中从字符串向量中读取
- 用字符串的向量分配字符串向量
- 如何使用 STL 算法将整数向量转换为字符串向量?
- C++ 中字符串向量的索引
- 如何根据第二列/第三列等对字符串向量进行排序?
- 如何从输入中获取字符串向量?
- 使用 C++-17,如何从字符串向量填充元组
- 对于循环增量器不能用作字符串向量的索引
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 如何从字符串向量中选择第 n 个位置?
- 如何将csv中的数据放入c++中的字符串向量中,而绝对没有任何作用
- 反转不带反转函数的字符串向量
- 如何在字符串向量中指向const int
- 如何在字符串向量中找到某个值