c++ - 如何按字母顺序按私有(private)字符串变量对对象 vector 进行排序

标签 c++ sorting object vector

我不知道如何通过名为 VIN 的成员变量之一对对象 vector 进行排序,该变量的数据类型为 string。我要执行冒泡排序或选择排序。我最熟悉冒泡排序,所以这是我试图采取的方向。但是,我知道我需要通过将它们全部设为大写或小写来比较这两个字符串。请记住,字符串中也会包含数字字符。

所以我的问题是: 1) 如何将字符串全部转换为小写或全部 ASCII 数字以及 2)临时变量应该是什么数据类型(类的数据类型或其他一些数据类型)。

这是我目前的(不完整的)代码:

    void sortInventory(vector<Vehicle> &carList)
    {
        bool swap; 
        string temp; 
        do
        {
            swap = false;

            for (int count = 0; count < carList.size(); count++)
            {
                if (carList[count].getVIN() > carList[count + 1].getVIN())
                {
                    temp = carList[count].getVIN();                                 
                    carList[count].getVIN() = carList[count + 1].getVIN();          
                    carList[count + 1].getVIN() = temp;                      
                    swap = true;                                               
                }
            }

        } while (swap);
}

这是我的类(class)声明:

class Vehicle
{
private:
    string VIN;

public:
    string getVIN();
    void   setVIN(string);

};

这是我的类实现:

string Vehicle::getVIN()
{   return VIN;     }

void Vehicle::setVIN(string input)
{   VIN = input;    }

谢谢!

最佳答案

您可以执行 std::sort(carList.begin(),carList.end(),vehicleCompare),其中 vehicleCompare 是您定义的比较函数。见 sort documentation 。然后,要大写,您可以使用 std::toupper ,如 this guide 所示。

std::string myToUpper(std::string in) {
    std::transform(in.begin(), in.end(),in.begin(), ::toupper);
    return in;
}

因此比较运算符(*) 将是:

bool vehicleCompare (const Vehicle a, const Vehicle b) {
    const std::string a_name = myToUpper(a.getVIN());
    const std::string b_name = myToupper(b.getVIN());
    return (a_name < b_name);
    }

关于 string comparison operator 的有用读物。

顺便说一句,你的string getVIN()方法应该是const,也就是说你应该把它的声明改为string getVIN() const.

如果您想保留排序功能,关键是无论如何您都必须定义一个合适的比较运算符,如此处所示。


为了明确回答您的第二个问题,temp 在 C++11 中可以是 auto,或者只是 std::string。那么您尝试分配 VIN 值的方式是错误的。鉴于您提供的界面,它应该是:

auto temp = carList[count].getVIN();                                 
carList[count].setVIN(carList[count + 1].getVIN() );          
carList[count + 1].setVIN(temp);

虽然当您开始有多个成员变量要复制时它仍然可能变得令人讨厌:您应该改为构建一个复制构造函数并将代码更改为:

auto temp = carList[count]; //you can use Vehicle instead of auto as type
carList[count] = carList[count + 1];          
carList[count + 1] = temp;

复制构造函数将是:

Vehicle(const Vehicle& in) 
  : VIN(in.getVIN() ) 
  {}

并且,到那时,您还需要一个来自字符串的构造函数和一个空构造函数。

Vehicle(std::string& inVIN) 
  : VIN(inVIN) 
  {}

Vehicle(const Vehicle& in) 
  {} //All input members get initialized through the default constructor.


(*) 请注意,这种比较方法不是最有效的,因为它使整个字符串大写,而前几个字符通常足以决定它们的顺序。因此,一种更有效的方法是一次将一个字符大写并进行比较,然后再决定是否将另一个字符大写。

关于c++ - 如何按字母顺序按私有(private)字符串变量对对象 vector 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29907135/

相关文章:

java - 使用java实现排序功能

algorithm - 为什么这种排序算法有效?

javascript - 将测验问题存储在对象数组中

ruby-on-rails - 如何将新的键值对插入到 Rails 4 中的获取数据库对象中

c++ - 两次使用 cin 时的意外行为

c++ - 将 C++ 字节数组转换为 C 字符串

java - android-列表排序不起作用

c++ - 如何在类中重新分配指针数组?

c++ - 从输入文件中逐行输入并使用 strtok() 进行标记化,然后输出到输出文件中

C++ sscanf_s 值不正确