剑指offer 把数组排成最小的数 atoi和itoa,pow
pow(x,y)在#include<math.h>文件中,计算x的y次方。
C++引入头文件:#include <stdlib.h> 或者 #include <cstdlib>
1、整数转化为字符串的方法:
1.1 atoi原型:注意:参数若为string类型一定转换成char*型(str.c_str())
- #include <stilib.h>或者#include<cstdlib>
- int atoi(const char *str);
atoi作用:把str字符串转换成整型数。如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字或结束符 \0 时停止转换,返回整型数。
itoa原型:
- #include<cstdlib>或者#include<stdlib.h>
- char *str[20];
- char* itoa(int num, char* str, int radix);
itoa作用:将value所代表的整数转换为字符串。其中,value是要转换的整数值,string是存储转换后值的字符数组,radix代表进制,radix=10就是十进制,radix=2就是二进制。
itoa值得注意的是:
1. 第二个参数只能是char*型,不能是string型;
2. 第二个参数在使用之前必须提前分配存储空间,在C++中就是new一块内存。
1.2 C++中整数转换为string。
stringstream( )
<sstream.h>
例如:
int hello=4;
stringstream ss;
ss<<hello;
string s=ss.str();
//调用string的方法
cout<<s.c_str()<<endl;
1.3 sprintf
sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。
char buf[10]; sprintf(buf, "%d", 100); string b = buf;
上面将100转化为字符串。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
思路:
1、最原始的方法使用permutation得到所有的全排列,然后将每个排列转化为整数,比较得出最小的整数。大数很容易越界,超出计算机表示范围。
#include<iostream> #include<vector> #include<sstream> #include<unordered_map> #include<math.h> using namespace std; void helper(vector<int>& numbers, vector<int> visited, vector<vector<int>> &result, vector<int> tmp) { if (tmp.size() == numbers.size()) { result.push_back(tmp); return; } for (int i = 0; i < numbers.size(); ++i) { if (i != 0 && numbers[i] == numbers[i - 1] && visited[i - 1] == 0 || visited[i] == 1) { continue; } visited[i] = 1; tmp.push_back(numbers[i]); helper(numbers, visited, result, tmp); tmp.pop_back(); visited[i] = 0; } } int permutation(vector<int>& numbers) { vector<vector<int>> result; int minNum = INT_MAX; vector<int> Tmp; if (numbers.size() == 0) { return 0; } vector<int> visited(numbers.size(), 0); helper(numbers, visited, result, Tmp); unordered_map<int, int> hashMap; for (int n : numbers) { int countPos = 0; int n1 = n; while (n != 0) { n = n / 10; ++countPos; } cout << "countPos " << countPos << " " << n1 << " "; hashMap.insert(make_pair(n1,countPos)); } for (vector<int> tmp : result) {//将数组转化为整数 int num = 0; int countP = 0; for (int i = 0; i < tmp.size(); ++i) { //cout << tmp[i] << " "; if (i == 0) { num = tmp[i]; } else { cout << "///" << hashMap[tmp[i - 1]]; countP += hashMap[tmp[i - 1]]; num += tmp[i] * (pow(10, countP)); } } cout << endl; cout << num << " "; cout << "*************************" << endl; if (minNum > num) { minNum = num; } } cout << minNum; return minNum; } string PrintMinNumber(vector<int>& numbers) { int result = permutation(numbers); istringstream ss(result); string s; ss >> s; return s; } int main() { vector<int> numbers{ 3,32,321 }; cout << PrintMinNumber(numbers) << endl; system("pause"); }
2、编写排序函数,利用sort函数,编写定制函数进行排序。
sort函数介绍。cmp函数不能修改传进去的参数。借口string a,或者const string &a;
在类里面写定制函数的时候,记得需要在定制函数前面加上static,原因是: 在类的成员函数使用带谓词的sort()函数
原因:sort()函数接受二元谓词,但是在类内定义的myCompare函数作为成员函数,实际上有三个参数,this指针、m、n。
解决方案:
1、将myCompare()函数挪到类定义的外面,即改为非成员函数;
2、将myCompare()函数定义为静态成员函数,没有this指针。
3、将myCompare()函数定义为类的友元函数,但是此时必须在类外声明该函数,否则,即使在类内定义了该友元函数,该函数仍然是不可见的。
class Solution { public: static bool cmp(const string& a,const string& b){ string s1 = a + b; string s2 = b + a; return s1 < s2; } string PrintMinNumber(vector<int> numbers) { string result; if(numbers.size() == 0){ return result; } vector<string> numString; for(int Tmp : numbers){ numString.push_back(to_string(Tmp)); } sort(numString.begin(),numString.end(),cmp); for(string tmp : numString){ result.append(tmp); } return result; } };
上面的方法需要证明:
组合数学里面的自反性,对称性,传递性。