把数组排成最小的数

题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

5段代码,主要区别在于sort()函数的第三个参数上。

sort与qsort:
sort函数定义与头文件中,其原型为:

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

主要用于容器中, 第3个参数可以是函数对象,也可以是函数指针;

qsort()函数位于头文件中,其原型为:

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

其参数为指针类型,特别是第三个参数为函数指针,而非函数对象。

附加一段参考代码

// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction (int i,int j) { return (i<j); }

struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33

  // using default comparison (operator <):
  std::sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33

  // using function as comp
  std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

  // using object as comp
  std::sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
  • 回归到本题:用一个StrComparator类,重载()操作——其实利用的就是函数对象
/**
 * 把数组排成最小的数
 * 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
 * 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

class StrComparator
{
public:
  bool operator()(string &a, string &b) const
  {
    string s1 = a + b;
    string s2 = b + a;
    return s1 < s2;
  }
};

class Solution {
public:
  string PrintMinNumber(vector<int> numbers) {
    if (numbers.empty()) {
      return strvec[0];
    }
    for (auto it = numbers.begin(); it != numbers.end(); it++) {
      strvec.push_back(IntToString(*it));
    }
    sort(strvec.begin(), strvec.end(), StrComparator());
    string result;
    for (auto it = strvec.begin(); it != strvec.end(); it++) {
      result += *it;
    }
    return result;
  }

  string IntToString(int i) {
    stringstream ss;
    ss << i;
    return ss.str();
  }

  // bool compare(int a, int b) {
  //   return a < b;
  // }

private:
  std::vector<string> strvec;
};

int main(int argc, char const *argv[]) {
  int arr[3] = {3,32,321};
  std::vector<int> intvec(arr, arr+3);
  Solution s;
  s.PrintMinNumber(intvec);
  return 0;
}
  • 定义一个函数对象;声明一个private函数对象compare作为sort函数的参数
/**
 * 把数组排成最小的数
 * 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
 * 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;
//定义函数对象
class StrComparator
{
public:
  bool operator()(string &a, string &b) const
  {
    string s1 = a + b;
    string s2 = b + a;
    return s1 < s2;
  }
};

class Solution {
public:
  string PrintMinNumber(vector<int> numbers) {
    if (numbers.empty()) {
      return strvec[0];
    }
    for (auto it = numbers.begin(); it != numbers.end(); it++) {
      strvec.push_back(IntToString(*it));
    }
    sort(strvec.begin(), strvec.end(), compare);
    string result;
    for (auto it = strvec.begin(); it != strvec.end(); it++) {
      result += *it;
    }
    return result;
  }

  string IntToString(int i) {
    stringstream ss;
    ss << i;
    return ss.str();
  }

  // bool compare(int a, int b) {
  //   return a < b;
  // }

private:
  std::vector<string> strvec;
  StrComparator compare;//声明函数对象
};

int main(int argc, char const *argv[]) {
  int arr[3] = {3,32,321};
  std::vector<int> intvec(arr, arr+3);
  Solution s;
  s.PrintMinNumber(intvec);
  return 0;
}
  • 用一个结构体,重载()操作——与上面两者类似,只不过把类换成了struct
/**
 * 把数组排成最小的数
 * 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
 * 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

struct StrComparator
{
  bool operator()(string &a, string &b) const
  {
    string s1 = a + b;
    string s2 = b + a;
    return s1 < s2;
  }
};

class Solution {
public:
  string PrintMinNumber(vector<int> numbers) {
    if (numbers.empty()) {
      return strvec[0];
    }
    for (auto it = numbers.begin(); it != numbers.end(); it++) {
      strvec.push_back(IntToString(*it));
    }
    sort(strvec.begin(), strvec.end(), StrComparator());
    string result;
    for (auto it = strvec.begin(); it != strvec.end(); it++) {
      result += *it;
    }
    return result;
  }

  string IntToString(int i) {
    stringstream ss;
    ss << i;
    return ss.str();
  }

  // bool compare(int a, int b) {
  //   return a < b;
  // }

private:
  std::vector<string> strvec;
};

int main(int argc, char const *argv[]) {
  int arr[3] = {3,32,321};
  std::vector<int> intvec(arr, arr+3);
  Solution s;
  s.PrintMinNumber(intvec);
  return 0;
}
  • 与第二种方法类似
/**
 * 把数组排成最小的数
 * 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
 * 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

struct StrComparator
{
  bool operator()(string &a, string &b) const
  {
    string s1 = a + b;
    string s2 = b + a;
    return s1 < s2;
  }
}compare;

class Solution {
public:
  string PrintMinNumber(vector<int> numbers) {
    if (numbers.empty()) {
      return strvec[0];
    }
    for (auto it = numbers.begin(); it != numbers.end(); it++) {
      strvec.push_back(IntToString(*it));
    }
    sort(strvec.begin(), strvec.end(), compare);
    string result;
    for (auto it = strvec.begin(); it != strvec.end(); it++) {
      result += *it;
    }
    return result;
  }

  string IntToString(int i) {
    stringstream ss;
    ss << i;
    return ss.str();
  }

  // bool compare(int a, int b) {
  //   return a < b;
  // }

private:
  std::vector<string> strvec;
};

int main(int argc, char const *argv[]) {
  int arr[3] = {3,32,321};
  std::vector<int> intvec(arr, arr+3);
  Solution s;
  s.PrintMinNumber(intvec);
  return 0;
}
  • 利用一个静态成员函数bool compare()
/**
 * 静态函数bool compare() 作为sort()函数的第三个参数
 */
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
class Solution {
public:
    static bool compare( const string &st1,const string &st2){
        string s1 = st1+st2;
        string s2 = st2+st1;
        return s1<s2;
    }
    string PrintMinNumber(vector<int> numbers) {
         string result;
        if(numbers.size()<=0){
            return result;
        }
        vector<string> strNum;
        for(int i=0;i<numbers.size();i++ ){
           stringstream ss;
            ss<<numbers[i];
            string s = ss.str();
            strNum.push_back(s);
        }
        sort(strNum.begin(),strNum.end(),compare);

        for(int i=0;i<strNum.size();i++){
            result.append(strNum[i]);
        }
        return result;

    }
};

int main(int argc, char const *argv[]) {
  int arr[3] = {3,32,321};
  std::vector<int> intvec(arr, arr+3);
  Solution s;
  s.PrintMinNumber(intvec);
  return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值