如何对字符串不区分大小写(不按字典顺序排序)?

时间:2013-11-25 18:45:29

标签: c++ string

我正在尝试按字母顺序(不按字典顺序)从文件中输入列表输入。所以,如果列表是:

Ç d 一个 B'/ P>

我需要它成为: 一个 b C d

不是词典排序: 一个 C b d

我正在使用字符串变量来保存输入,所以我正在寻找一些方法来修改我要比较的大写或小写的字符串,或者如果有一些更简单的方法来强制进行字母比较,请传授那种智慧。谢谢!

我还应该提到,我们仅限于以下用于此任务的库:iostream,iomanip,fstream,string,以及C库,如cstring,cctype等。

5 个答案:

答案 0 :(得分:1)

您不必在排序前修改字符串。您可以使用不区分大小写的单字符比较器和std::sort来对它们进行排序:

bool case_insensitive_cmp(char lhs, char rhs) {
  return ::toupper(static_cast<unsigned char>(lhs) < 
         ::toupper(static_cast<unsigned char>(rhs);
}

std::string input = ....;
std::sort(input.begin(), input.end(), case_insensitive_cmp);

答案 1 :(得分:1)

  

看起来我只需要通过一些非常繁琐的字符提取方法和每个字符串的顶部来解决这个问题。

通过限制使用算法,迭代器等,将单个字符串转换为大写字母并进行比较并不会特别糟糕。比较逻辑大约是四行代码。尽管不必编写那些必须编写排序算法的四行会更加困难和乏味。 (好吧,假设toupper的通常C版本首先是可以接受的。)

下面我展示一个简单的strcasecmp()实现,然后将其用于使用受限库的完整程序。 strcasecmp()本身的实现不使用受限库。

#include <string>
#include <cctype>
#include <iostream>

void toupper(std::string &s) {
  for (char &c : s)
    c = std::toupper(c);
}

bool strcasecmp(std::string lhs, std::string rhs) {
  toupper(lhs); toupper(rhs);
  return lhs < rhs;
}

// restricted libraries used below

#include <algorithm>
#include <iterator>
#include <vector>

// Example usage:
//  > ./a.out <<< "C d A b"
//  A b C d
int main() {
  std::vector<std::string> input;
  std::string word;
  while(std::cin >> word) {
    input.push_back(word);
  }

  std::sort(std::begin(input), std::end(input), strcasecmp);
  std::copy(std::begin(input), std::end(input),
            std::ostream_iterator<std::string>(std::cout, " "));
  std::cout << '\n';
}

答案 2 :(得分:0)

在qsort()中使用strcasecmp()作为比较函数。

答案 3 :(得分:0)

我不完全确定如何编写它,但你想要做的是将字符串转换为小写或大写。

如果字符串以数组开头,则将遍历列表,并按顺序将索引保存在(int)数组中。

答案 4 :(得分:0)

如果你只是比较字母,那么一个可怕的黑客将会屏蔽每个字符的高位两位。然后大写和小写字母相互叠加。