如何按字母顺序按私有字符串变量对对象进行排序

时间:2015-04-27 22:33:04

标签: c++ sorting object vector

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

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

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

string

这是我的班级声明:

    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 Vehicle
{
private:
    string VIN;

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

};

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以执行std::sort(carList.begin(),carList.end(),vehicleCompare),其中vehicleCompare是您定义的比较功能。见here。然后,为了大写,您可以使用sort documentation,如std::toupper

所示
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);
    }

有关this guide的有用阅读。

顺便说一下,您的string getVIN()方法应为const,即您应将其声明更改为string getVIN() const

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

要专门回答您的第二个问题,temp可能是{+ 1}}在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() ) 
  {}

<小时/> (*)请注意,这种比较方法不是最有效的,因为它使整个字符串大写,而前几个字符通常足以决定它们的顺序。因此,更有效的方法是在判断是否大写另一个字符之前,先对一个字符进行大写并进行比较。

答案 1 :(得分:1)

回答问题1:您可以创建一个将std :: string转换为upper的简单函数。

void string_to_upper(string &s) {
  for(int l = 0; l < s.length(); ++l) {
     s[l] = toupper(s[l]);
  }
}

答案 2 :(得分:1)

首先,您的Vehicle::getVIN()方法应标记为 const ,以实现正确的const正确性:

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

然后,请注意,您不需要重新发明轮子并在C ++的生产代码中从头开始重新实现排序算法(除非这是一个关于编写排序代码的学习练习/家庭作业)。

您可以简单地使用STL中实现的标准std::sort()算法,并使用方便的C ++ 11 lambda自定义比较条件,例如:

// std::vector<Vehicle> carList;

std::sort(carList.begin(), carList.end(), 
    [](const Vehicle& v1, const Vehicle& s2)
    {
        /* Code implementing custom Vehicle comparison */
    }
);

你在lambda中的代码可能是这样的:

    [](const Vehicle& v1, const Vehicle& s2)
    {
        // Use stricmp() to compare strings in a case insensitive way
        return (stricmp(v1.getVIN().c_str(), v2.getVIN().c_str()) < 0);
    }

您可以使用stricmp()或其他方法,而不是调用boost::to_upper()。在StackOverflow上的这个帖子中:

  

Case insensitive string comparison in C++