与1408的字符串与数组的搭配限制和传统实现:
就用一次的简易函数?
[caoture] (params) opt -> ret {body;};
[r = arr.data()](int a, int b){return r[a] < r[b];}
class Solution {
public:
vector<int> arrayRankTransform(vector<int>& arr) {
vector<int> idx(arr.size());
iota(idx.begin(), idx.end(), 0);
sort(idx.begin(), idx.end(), [r = arr.data()](int a, int b){return r[a] < r[b];});
//取到指针会更快
int rk = 0, rear = INT_MIN;
for(int x: idx){
if(arr[x] != rear) ++rk;
rear = arr[x];
arr[x] = rk;
}
return arr;
}
};
比较重要的地方就是sort的第三个参数,即lambda表达式。这道题由于要按照排序arr的方式排序其下标数组idx,即lambda表达式作为函数代替了传统的比较函数。且两个数组之间的联系都用int型变量,因此可以直接进行调用,arr的排序方法,作用于idx(sort前两个参数决定)。
但若出现容器装着不同类型的数据呢?这样直接的方法是否依然适用?答案是否。引出1408:
class Solution {
public:
vector<string> stringMatching(vector<string>& words) {
int wordsSize = words.size();
vector<string>result;
vector<int>everySize;
for (size_t i = 0; i < wordsSize; i++)
{
everySize.push_back(words[i].size());
}//初始化一波size数组为自定义bool base
sort(words.begin(), words.end(), [r = everySize.data()](int a,int b){return r[a] < r[b];});
//lamba表达式,sort的第三参,字符串数组的排序
for (size_t i = 0; i < wordsSize; i++)
{
for (size_t j = i+1; j < wordsSize; j++) {
if(words[j].find(words[i]) != string::npos){
result.emplace_back(words[i]);
break;
}
}
}
return result;
}
};
// @lc code=end
显然,我想通过对其对应字符串长度的排序方式来排序words,但是很遗憾,由于lambda表达式的局限性,入参是两个int的情况下是无法直接对应装着 string 的数组的(cmp函数不匹配)。那么要是直接写cmp函数的方式该如何实现呢?这里问了身边的同事:
bool cmp(const std::string &a, const std::string &b){
if (a.size() != b.size()){
return a.size() < b.size();
} else/* 考虑到两者size相等的情况 */{
return a < b;
}
}
经过测试后,排序是成功的,那么写成lambda形式呢?
[](string &str1,string &str2){
if (str1.size() != str2.size()){
return str1.size() < str2.size();
} else/* 考虑到两者size相等的情况 */{
return str1 < str2;
}
}
感觉和上面的bool-cmp没啥不一样,只是自动生成了函数返回值和名。。。。蚌埠了。
最后,挂个官方的暴力法题解吧:
class Solution {
public:
vector<string> stringMatching(vector<string>& words) {
vector<string> ret;
for (int i = 0; i < words.size(); i++) {
for (int j = 0; j < words.size(); j++) {
if (i != j && words[j].find(words[i]) != string::npos) {
ret.push_back(words[i]);
break;
}
}
}
return ret;
}
};
其中也有需要注意的点,即找字符串的子字符串的方法:words[j].find(words[i]) != string::npos
.
1、想通过排序A的方式排序B,要是想使用lambda表达式的形式,那AB的入参形式一定要一样。
2、想通过模仿1131的形式,来通过建立字符串长度数组(对应角标是其大小对应的字符串)后,再对字符串数组进行排序,且想要其排序方式按照长度数组排序顺序的想法固然是是好的,但利用lambda表达式的形式并不ok,因为入参不一样,两个string和两个int并无法对应,系统无法识别。建议使用传统cmp或不简洁的lambda表达式。
1、那通过将其长度作为主键利用map数据结构进行排序呢?啊,map不允许key重复啊,要保持映射唯一性。
2、映射不可以轻易建造捏,因为不管是string,还是长度都有可能重复。
anyway,最后的解决方法就是像上面的总结说的,同参用lambda简单,不同参要是可以直接调其对象属性的情况下,还是写一个cmp吧。