当前位置: 首页 > news >正文

【跟学C++】C++STL标准模板库——算法详细整理(中)(Study18)

文章目录

    • 1、简介
    • 2、STL算法分类及常用函数
      • 2.1、变序算法(一)
        • 2.2.1 初始化算法(2个)
        • 2.2.2 修改算法(2个)
        • 2.2.3 复制算法(6个)
        • 2.2.4 删除算法(6个)
    • 3、总结

 ============================ 【说明】 ===================================================
  大家好,本专栏主要是跟学C++内容,自己学习了这位博主【 AI菌】的【C++21天养成计划】,讲的十分清晰,适合小白,希望给这位博主多点关注、收藏、点赞。
  主要针对所学内容,通过自己的理解进行整理,希望大家积极交流、探讨,多给意见。后面也会给大家更新,其他一些知识。若有侵权,联系删除!共同维护网络知识权利!
 =======================================================================================
   写在前面
  至此,我们了解了C++的基本语法,但是进一步学习C++,数据结构是必不可少的内容。 数据结构与算法决定了代码测存储方式,以及代码执行效率。
  数据结构的重要性不言而喻, 关于数据结构的基本知识可以转至本人另一专栏====>【 数据结构】。同样也可以阅读博主【 AI菌】写的【 数据结构与算法】,比较通俗易懂,可以学习学习!


1、简介

  上一节,详细介绍了STL标准模板库——算法整理(上)相关内容,介绍了STL算法分类及常用函数,详细说明非变序算法的常用函数,今天我们继续介绍关于变序算法一部分常用函数及注意点。

2、STL算法分类及常用函数

  STL算法模板库分为两大类:非变序与变序。对于这两种类别如何理解?下面就详细介绍两大类以及各函数的具体应用。

2.1、变序算法(一)


2.2.1 初始化算法(2个)

函数名解释
fill()将指定值分配给指定范围内的元素。
fill_n()将指定值分配给前n个每个元素。

  (1) fill()/ fill_n()

  STL模板库提供了一种为元素序列填入给定值的简单方式,即fill()fill_n();
  fill():将指定范围内的元素设置为指定值,fill() 会填充整个序列
  fill_n():将n个元素设置为指定的值。接受的参数包括:起始位置元素的个数以及设置的值
  
  关于fill()fill_n()案例如下:

#include <iostream>
#include <map>
#include<list>
#include<functional>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;void DisplayFill(vector <int> vec)
{for (int i = 0; i<vec.size(); i++)cout << vec[i] << " ";cout << endl;}//1、fill/fill_n
int main() {// 初始化长度为3的数组 vector <int> vec(3);// 用9填满容器 fill(vec.begin(), vec.end(), 9);DisplayFill(vec);vec.resize(6);DisplayFill(vec);// 从第三个元素之后,填3个-9fill_n(vec.begin() + 3, 3, -9);DisplayFill(vec);return  0;
}

在这里插入图片描述

  


2.2.2 修改算法(2个)

函数名解释
for_each()对指定范围内的每个元素,执行指定的操作。
transform()对指定范围内的每个元素,执行指定的对指定范围内的每个元愫,执行指定的一元函数。

  (1)for_each

  for_each():是对区间[first,last)(注意左闭右开)上的每一个元素调用function,第三个参数可以全局函数、函数对象
、lambda表达式、并且是一个一元函数。for_each()具体定义如下:

template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction function );

  参数first,last:指定该算法操作的区间[first, last);

  参数function : 一元函数,即UnaryFunction ,可以是全局函数(函数指针)\函数对象、lambda等、默认按值传递;第三个参数function默认是按值传递的也就是说for_each()内部操作的是function的副本,另外,返回值也是按值返回的。当然,也可以打破这种限制(参考:Effective STL 的38条款)

  返回值:返回function 的一个副本,function的任何返回值都将被忽略;
  
  关于for_each()案例如下:

//2、for_each
static void printElement(int &item) {cout << item << " ";}class Printer {
public:void operator()(int & item) {cout << item << " ";}
};int main() {int printArray[] = {1,3,5,4,78,25};//第三个参数为static全局函数for_each(begin(printArray), end(printArray), printElement);cout << endl;//第三个参数为lambda表达式for_each(begin(printArray), end(printArray), [](int &item) {cout << item << " "; });cout << endl;//第三个参数为函数对象for_each(begin(printArray), end(printArray),Printer());cout << endl;return 0;
}

在这里插入图片描述

//计算容器/数组元素的sum。
class Sum {public:Sum() :sum{ 0 }{}void operator()(const int& item){sum += item;}int getSum() {return sum;}
private:int sum;
};int main(int argc, char *argv[])
{std::vector<int> nums{ 0,1,2,3,4,5,6,7,8,9 };Sum elements = std::for_each(nums.begin(), nums.end(), Sum());std::cout << elements.getSum() << std::endl;return 0;
}

在这里插入图片描述

  (2)transform

  transform() :可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。

  这个算法有一个版本和 for_each() 相似,可以将一个一元函数应用到元素序列上来改变它们的值,但这里有很大的区别for_each() 中使用的函数的返回类型必须为 void,而且可以通过这个函数的引用参数来修改输入序列中的值;而 transform() 的二元函数必须返回一个值,并且也能够将应用函数后得到的结果保存到另一个序列中。
  第二个版本的 transform() 允许将二元函数应用到两个序列相应的元素上,但先来看一下如何将一元函数应用到序列上。在这个算法的这个版本中,它的前两个参数是定义输入序列的输入迭代器,第 3 个参数是目的位置的第一个元素的输出迭代器,第 4 个参数是一个二元函数。
  
  关于transform案例如下:


//3、transform
double Transform(double &num) {double result = 32.0 + 9.0*num / 5.0;cout << result<<endl;return result;
}
//案例1:将摄氏度改为华氏度
int main() {vector<double> N1{25.5, 26.1, 27.0, 23.8, 24.0};vector<double> N2(N1.size());//第四个参数统一采用static全局函数,也可采用lambda表达式:[](double temp){ return 32.0 + 9.0*temp/5.0; }// 第3 个参数是目的位置的第一个元素的输出迭代器cout << "Way 1:" << endl;transform(begin(N1), end(N1), rbegin(N2), Transform);cout << endl;// 第3个参数是用 back_insert_iterator 作为 transform() 的第三个参数,可以将结果保存到空的容器中cout << "Way 2:" << endl;transform(begin(N1), end(N1), back_inserter(N2), Transform);cout << endl;// 第3个参数可以是指向输入容器的元素的迭代器,是输入序列的开始迭代器cout << "Way 3:" << endl;transform(begin(N1), end(N1),begin(N2),Transform);cout << endl;
}

在这里插入图片描述
  way 1:它的前两个参数是定义输入序列的输入迭代器,第 3 个参数是目的位置的第一个元素的输出迭代器,第 4 个参数是一个二元函数。这个函数必须接受来自输入序列的一个元素为参数,并且必须返回一个可以保存在输出序列中的值。
  way 2:为了保存全部结果,生成的 N2需要一定个数的元素。因此第三个参数是 N2的开始迭代器。通过用 back_insert_iterator 作为 transform() 的第三个参数,可以将结果保存到空的容器。
  way 3:第三个参数是输入序列的开始迭代器,应用第 4 个参数指定的函数的结果会被存回它所运用的元素上。

  

//案例2
int main111(){
std::vector<string> words{ "one", "two", "three", "four","five" };
std::vector<size_t> hash_values;
transform(std::begin(words), std::end(words), std::back_inserter(hash_values), std::hash<string>()); // string hashing function
copy(std::begin(hash_values), std::end(hash_values), std::ostream_iterator<size_t> {std::cout, " "});
cout << std::endl;
}

在这里插入图片描述

  输入序列包含 string 对象,并且应用到元素的函数是一个定义在 string 头文件中的标准的哈希函数对象。这个哈希函数会返回 size_t 类型的哈希值,并且会用定义在 iterator 头文件中的辅助函数 back_inserter() 返回的 back_insert_iterator 将这些值保存到 hash_values 容器中。

  


//案例3
int main() {
std::deque<string> names{ "Stan Laurel", "Oliver Hardy", "Harold Lloyd" };
std::transform(std::begin(names), std::end(names), std::begin(names), [](string& s) { std::transform(std::begin(s), std::end(s), std::begin(s), ::toupper); return s; });
std::copy(std::begin(names), std::end(names), std::ostream_iterator<string>{std::cout, " "});
std::cout << std::endl;
return 0;
}

在这里插入图片描述
  transform() 算法会将 lambda 定义的函数应用到 names 容器中的元素上。这个 lambda 表达式会调用 transform(),将定义在 cctype 头文件中的 toupper() 函数应用到传给它的字符串的每个字符上。它会将 names 中的每个元素都转换为大写。

  总结:
  应用二元函数的这个版本的 transform() 含有 5 个参数:
    前两个参数是第一个输入序列的输入迭代器。
    第3个参数是第二个输入序列的开始迭代器,显然,这个序列必须至少包含和第一个输入序列同样多的元素。
    第4个参数是一个序列的输出迭代器,它所指向的是用来保存应用函数后得到的结果的序列的开始迭代器。
    第5个参数是一个函数对象,它定义了一个接受两个参数的函数,这个函数接受来自两个输入序列中的元素作为参数,返回一个可以保存在输出序列中的值。

  


2.2.3 复制算法(6个)

函数名解释
copy()对指定范围内的元素复制到另一范围。
copy_n()从源容器复制指定个数的元素到目的容器中。
copy_if()可以从源序列复制使谓词返回 true 的元素,所以可以把它看作一个过滤器。
copy_backward()对指定范围内的元素复制到另一范围,复制到目标范围的元素顺序反转
reverse_copy()将源序列复制到目的序列中,目的序列中的元素是逆序的。
rotate_copy()在新序列中生成一个序列的旋转副本,并保持原序列不变。

  (1)copy

  copy():提供一种方便的方式来输出容器中的元素。函数copy()作为泛型算法的一部分,任何容器类型都可以使用。copy()函数不只是输出容器的元素。通常,它允许我们复制元素从一个地方到另一个地方。例如输出vector的元素或复制vector的元素到另一个vector,我们可以使用copy()函数。该函数模版copy的原型为:

template <class inputIterator, class outputIterator>
outputIterator copy(inputIterator first1, inputIterator last, outputIterator first2);

  参数first1:指定了开始拷贝元素的位置;
  参数last:指定了结束位置。
  参数first2:指定了拷贝元素到哪里。
  因此,参数first1和last指定了源;参数first2指定了目的。
  
  关于copy案例如下:


//==================4、copy
int main() {int intArray[] = { 1,2,3,4,5 };vector<int> copyList(5);//ex.1cout << "ex.1:" << endl;copy(intArray, intArray + 5, copyList.begin());cout  << endl;//ex.2cout << "ex.2:" << endl;copy(copyList.rbegin() + 2, copyList.rend(), copyList.rbegin());cout << endl;//ex.3 迭代器的方式cout << "ex.3 迭代器:" << endl;ostream_iterator<int> print(cout, " ");copy(intArray, intArray + 5, print);cout << endl;copy(copyList.begin(), copyList.end(), print);cout << endl;return 0;
}

在这里插入图片描述
  ex.1:该语句复制从位置intArray开始的元素,从数组的第一个组件intArray开始,直到intArray + 5 -1(即为intArray + 4,其为数组intArray的最后一个元素)到容器copyList。
  ex.2:其中rbegin(reverse begin)函数返回容器中最后一个元素的指针。用于以反向来对容器中元素进行处理。因此,vecList.rbegin() + 2返回容器vecList中倒数第三个元素的指针。相似地,rend(reverse end)函数返回容器中指向第一个元素的指针。所以,上边的语句把容器vecList中的元素右移两个位置。
  ex.3:该语句创建screen作为ostream迭代器(元素类型为int)。迭代器screen有两个参数:对象cout和空格(a space)因此,迭代器screen使用对象cout来初始化。当该迭代器输出元素时,它们通过空格来分开。

  
  (2)copy_n

  copy_n() :可以从源容器复制指定个数的元素到目的容器中。
  第一个参数:指向第一个源元素的输入迭代器;
  第二个参数:需要复制的元素的个数;
  第三个参数:指向目的容器的第一个位置的迭代器。
  这个算法会返回一个指向最后一个被复制元素的后一个位置的迭代器,或者只是第三个参数——输出迭代器——如果第二个参数为 0
  
  关于copy_n案例如下:

//==================4.1、copy_n
int main() {vector<string> names{ "C++","Java","Python","C#" };vector<string> more_names{ "C","JavaScript" };copy_n(rbegin(names)+1, 3, inserter(more_names, begin(more_names)));for (int i = 0; i < more_names.size(); i++){cout << more_names[i] << " ";}cout << endl;return 0;
}

在这里插入图片描述
  这个 copy_n() 操作会从 names 的倒数第二个元素开始复制 3 个元素到关联容器 more_names 中。目的容器是由一个 vector容器的 insert_iterator 对象指定的,它是由 inserter() 函数模板生成的。insert_iterator 对象会调用容器的成员函数 insert() 来向容器中添加元素。

  
  (3)copy_if

  copy_if() :可以从源序列复制使谓词返回 true 的元素,也可以把它看作一个过滤器。
  前两个参数定义源序列的输入迭代器;
  第三个参数是指向目的序列的第一个位置的输出迭代器;
  第 4 个参数是一个谓词。会返回一个输出迭代器,它指向最后一个被复制元素的下一个位置。

  
  关于copy_if案例如下:

int main() {vector<string> names{ "A1", "Beth", "Carol", "Dan", "Eve","Fred", "George", "Harry", "Iain", "Joe" };vector<string> more_names{ "Jean", "John" };rsize_t max_length(4);cout << "names【origin】:" << endl;copy(begin(names), end(names), ostream_iterator<string>{cout, " "});cout << endl;cout << "more_names【origin】:" << endl;copy(begin(more_names), end(more_names), ostream_iterator<string>{cout, " "});cout << endl;copy_if(begin(names), end(names), inserter(more_names, begin(more_names)), [max_length](const string&s) {return s.length() <= max_length; });//使用copy()显示more names内容cout << "after copy_if more_names【new】:" << endl;copy(begin(more_names), end(more_names), ostream_iterator<string>{cout, " "});cout << endl;return 0;
}

在这里插入图片描述
  第 4 个参数的 lambda 表达式所添加的条件,这里的 copy_if() 操作只会复制 names 中的 4 个字符串或更少。目的容器是一个 unordered_set 容器 more_names,它已经包含两个含有 4 个字符的名称,insert_itemtor 会将元素添加到限定的关联容器中。为了查看容器more_names内的元素,我们可以采用copy() 算法列出。

//流迭代器示例vector<string> names{ "Al", "Beth", "Carol", "Dan", "Eve","Fred", "George", "Harry", "Iain", "Joe" };size_t max_length{ 4 };copy_if(begin(names), end(names), ostream_iterator< string> {cout, " "}, [max_length](const string& s) { return s.length() > max_length; });cout << endl;return 0;

在这里插入图片描述

  copy_if()目的容器也可以是一个流迭代器,将 names 容器中含有 4 个以上字符的名称写到标准输出流中。

	//输入流迭代器作为算法源unordered_set<string> names;size_t max_length{ 4 };cout << "Enter names of less than 5 letters. Enter Ctrl+Z on a separate line to end:\n";copy_if(istream_iterator<string>{cin}, istream_iterator<string>{}, inserter(names, begin(names)), [max_length](const string& s) { return s.length() <= max_length; });copy(begin(names), end(names), ostream_iterator <string>{cout, " "});cout << endl;

在这里插入图片描述
  输入流迭代器可以作为 copy_if() 算法的源也可以将它用在其他需要输入迭代器的算法上。容器 names 最初是一个空的 unordered_set。只有当从标准输入流读取的姓名的长度小于或等于 4 个字符时,copy_if() 算法才会复制它们
  超过 5 个字母的姓名可以从 cin 读入,但是被忽略掉,因为在这种情况下第 4 个参数 的判定会返回 false。因此,输入的 10 个姓名里面只有 6 个会被存储在容器中。

  

  (4)copy_backward

  copy_backward() :该算法不会逆转元素的顺序,只会像 copy() 那样复制元素,但是从最后一个元素开始直到第一个元素。

  关于copy()与copy_backward()的区别如下:

  (1) copy_backward
  copy_backward() 会复制前两个迭代器参数指定的序列。第三个参数是目的序列的结束迭代器,通过将源序列中的最后一个元素复制到目的序列的结束迭代器之前,源序列会被复制到目的序列中,
如下图 所示。copy_backward() 的 3 个参数都必须是可以自增或自减的双向迭代器,这意味着这个算法只能应用到序列容器的序列上。


(图片来源:http://m.biancheng.net/view/605.html)

  图中说明了源序列 from 的最后一个元素是如何先被复制到目的序列 to 的最后一个元素的。从源序列的反向,将每一个元素依次复制到目的序列的前一个元素之前的位置。在进行这个操作之前,目的序列中的元素必须存在,因此目的序列至少要有和源序列一样多的元素,但也可以有更多。copy_backward() 算法会返回一个指向最后一个被复制元素的迭代器,在目的序列的新位置,它是一个开始迭代器。

  (1) copy
  在序列重叠时,可以用 copy() 将元素复制到重叠的目的序列剩下的位置——也就是目的序列第一个元素之前的位置。如果想尝试用 copy() 算法将元素复制到同一个序列的右边,这个操作不会成功,因为被复制的元素在复制之前会被重写。如果想将它们复制到右边,可以使用 copy_backward(),只要目的序列的结束迭代器在源序列的结束迭代器的右边。下图说明了在将元素复制到重叠的序列的右边时,这两个算法的不同。
在这里插入图片描述
(图片来源:http://m.biancheng.net/view/605.html)

  图中展示了在序列右边的前三个位置运用 copy()copy_backward() 算法的结果。在想将元素复制到右边时,copy() 算法显然不能如我们所愿,因为一些元素在复制之前会被重写。在这种情况下,copy_backward() 可以做到我们想做的事。相反在需要将元素复制到 序列的左边时,copy() 可以做到,但 copy_backward() 做不到。

  
  关于copy_backward案例如下:

//==================4.2、copy_backward
int main() {vector<string> name{ "Al", "Beth", "Carol", "Dan", "Eve","Fred" };cout << "name【origin】:" << endl;copy(begin(name), end(name), ostream_iterator<string>{cout, " "});cout << endl;name.resize(name.size() + 2);copy_backward(begin(name), begin(name)+6,end(name));cout << "after copy_backward name【origin】:"<<endl;copy(begin(name), end(name), ostream_iterator<string>{cout, " "});cout << endl;return 0;
}

在这里插入图片描述
  为了能够在右边进行序列的反向复制操作,需要添加一些额外的元素,可以通过使用 vector的成员函数 resize() 来增加 vector容器的元素个数。copy_backward() 算法会将原有的元素复制到向右的两个位置,保持前两个元素不变。

  
  (5)reverse_copy

  reverse_copy()可以将源序列复制到目的序列中,目的序列中的元素是逆序的
  前两个参数迭代器参数必须是双向迭代器。
  目的序列由第三个参数指定,它是目的序列的开始迭代器,也是一个输出迭代器。
  如果序列是重叠的,函数的行为是未定义的。这个算法会返回一个输出迭代器,它指向目的序列最后一个元素的下一个位置。
  
  关于reverse_copy案例如下:

//==================4.4、reverse_copy
int main() {string OneSentance;cout << "please input one swntance and Ctrl+Z to end:" << endl;getline(cin, OneSentance);if (cin.eof()){exit(0);}//复制相同字符至AnotherSentance并将所有字母大写string AnotherSentance;copy_if(begin(OneSentance), end(OneSentance),back_inserter(AnotherSentance) ,[](char ch) {return isalpha(ch); });for_each(begin(AnotherSentance), end(AnotherSentance), [](char &ch) {ch = toupper(ch); });//判断是否为回文string reversed;reverse_copy(begin(AnotherSentance), end(AnotherSentance), back_inserter(reversed));cout << " ' " << OneSentance << " ' " << (AnotherSentance == reversed ? "is" : "is not") << " a palindrome!" << endl;return 0;
}

在这里插入图片描述

  该程序目的是检查一条语句(也可以是很多条语句)是否是回文的
  回文语句是指正着读或反着读都相同的句子,前提是忽略一些像空格或标点这样的细节
  while 使我们可以检查尽可能多的句子。用 getline() 读一条句子到 OneSentence 中。如果读到 Ctrl+Z,输入流中会设置 1 个eof()标志,它会结束循环。用 copy_if()OneSentence 中的字母复制到 AnotherSentence 。这个 lambda 表达式只在参数是字母时返回 true,所以其他的任何字符都会被忽略。然后用 back_inserter() 生成的 back_insert_iterator 对象将这些字符追加到 AnotherSentence。

  for_each() 算法会将三个参数指定的函数对象应用到前两个参数定义的序列的元素上,因此这里会将 AnotherSentence中的字符全部转换为大写。然后用 reverse_copy() 算法生成和 AnotherSentence的内容相反的内容。比较 AnotherSentencereversed 来判断输入的语句是否为回文。

  

  (6)rotate_copy

  rotate_copy() :在新序列中生成一个序列的旋转副本,并保持原序列不变
  前 3 个参数copy() 是相同的;
  第 4 个参数是一个输出迭代器,它指向目的序列的第一个元素。
  这个算法会返回一个目的序列的输出迭代器,它指向最后一个被复制元素的下一个位置。
  
  关于rotate_copy案例如下:

//==================4.4、rotate_copyint main() {vector<int> words{1,2,3,4,5,6,7,8};auto start = find(begin(words), end(words), 2);auto endd = find(begin(words), end(words), 8);cout << "原序列:" << endl;copy(begin(words), end(words), ostream_iterator<int>{cout, " "});cout << endl;vector<int> copy_word;rotate_copy(start, find(begin(words), end(words), 5), endd, back_inserter(copy_word));cout << "旋转副本序列:" << endl;copy(begin(copy_word), end(copy_word), ostream_iterator<int>{cout, " "});cout << endl;cout << "原序列未变化:" << endl;copy(begin(words), end(words), ostream_iterator<int>{cout, " "});cout << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述
  words 中从1 到 8的元素生成一个旋转副本。通过使用 back_insert_iterator 将复制的元素追加到 copy_word容器中,back_insert_iterator 会调用 words_copy 容器的成员函数 push_back() 来插入每个元素。

  


2.2.4 删除算法(6个)

函数名解释
remove()在指定范围内,将指定的元素删除。
remove_if()在指定范围内,将满足指定一元谓词的元素删除。
remove_copy()将源序列中除包含指定删除值外的所有元素复制到目标范围。
remove_copy_if()将源序列中除满足指定一元谓词删除值外的所有元素复制到目标范围。
unique()比较指定范围内的相邻元素,并删除重复的元素
unique_copy()将源范围内的所有元素复制到目标范围,但相邻的重鰒元素除外

  
  (1)remove

  remove()从前两个正向迭代器参数指定的序列中移除和第三个参数相等的对象。基本上每个元素都是通过用它后面的元素覆盖它来实现移除的。它会返回一个指向新的最后一个元素之后的位置的迭代器。
  
  关于remove案例如下:

//==================5、remove
int main() {deque<double> measures{ 21.5, 14.8, 0.0, 43.1, 0.0, 24.1, 0.0, 26.7, 0.0 };measures.erase(remove(begin(measures), end(measures), 0.0), end(measures));//remove(begin(measures), end(measures), 0.0);copy(begin(measures), end(measures), ostream_iterator<double>{cout, " "});cout << endl;return 0;
}

在这里插入图片描述
remove的结果:
在这里插入图片描述
  measures中不应包含为 0 的测量值。(重点)remove() 算法会通过左移其他元素来覆盖它们,通过这种方式就可以消除杂乱分布的 0。remove() 返回的迭代器指向通过这个操作得到的新序列的尾部,所以可以用它作为被删除序列的开始迭代器来调用 measures的成员函数 erase()。注释说明容器中的元素没有被改变。

  关于remove和erase区别可以参考这篇博文:C++ remove和erase

  

  (2)remove_if

  remove_if()从序列中移除和给定值匹配的元素。其中,谓词会决定一个元素是否被移除;它接受序列中的一个元素为参数,并返回一个布尔值
  remove_if()返回一个指向被修剪的序列的最后一个元素迭代器。remove_if()并不会实际移除序列[start, end)中的元素,所有的元素都还在容器里面实际做法是remove_if()将所有应该移除的元素都移动到了容器尾部并返回一个分界的迭代器。 移除的所有元素仍然可以通过返回的迭代器访问到。为了实际移除元素,必须对容器自行调用erase()以擦除需要移除的元素

  
  关于remove_if案例如下:

//==================5.1、remove_copy
int main(){using Name = pair<string, string>; // First and second nameset<Name> blackNames{ Name{ "Al", "Bedo" }, Name{ "Ann", "Ounce" }, Name{ "Jo","King" } };deque<Name> VIPNames{ Name{ "Stan", "Down" }, Name{ "Al", "Bedo" }, Name{ "Dan", "Druff" },Name{ "Di", "Gress" }, Name{ "Ann", "Ounce" }, Name{ "Bea", "Gone" } }; VIPNames.erase(remove_if(begin(VIPNames), end(VIPNames), [&blackNames](const Name& name) { return blackNames.count(name); }), end(VIPNames));for_each(begin(VIPNames), std::end(VIPNames), [](const Name& name) {std::cout << '"' << name.first << " " << name.second << "\" "; });cout << endl;  
return 0;
}

在这里插入图片描述
  这段代码用来模拟候选人申请成为倶乐部会员
  将黑名单的姓名被保存在 blackNames中,它是一个集合。当前申请成为会员的候选人被保存在 VIPNames容器中,它是一个 deque 容器。用 remove_if() 算法来保证不会有 blackNames中的姓名通过甄选过程。这里的谓词是一个以引用的方式捕获 blackNames容器的 lambda 表达式。当参数在容器中存在时,set 容器的成员函数 count() 会返回 1。谓词返回的值会被隐式转换为布尔值,因此对于每一个出现在 blackNames中的候选人,谓词都会返回 true,然后会将它们从 VIPNames中移除。注释中显示了通过甄选的候选人。

  
  (3)remove_copy

   remove_copy():如果想保留原始序列,并生成一个移除选定元素之后的副本。可以使用remove_copy()算法。

  
  关于remove_copy案例如下:


//==================5.2、remove_copy
int main() {deque<double> measures{ 21.5, 14.8, 0.0, 43.1, 0.0, 24.1, 0.0, 26.7, 0.0 };vector<double> samples;cout << "原序列:" << endl;copy(begin(measures), end(measures), ostream_iterator<double>{cout, " "});cout << endl;remove_copy(begin(measures), end(measures), back_inserter(samples), 0.0);cout << "remove_copy后原序列:" << endl;copy(begin(measures), end(measures), ostream_iterator<double>{cout, " "});cout << endl;cout << "remove_copy后目的序列(samples):" << endl;copy(begin(samples), end(samples), ostream_iterator<double>{cout, " "});cout << endl;return 0;}

在这里插入图片描述
  measures容器中的非零元素会被复制到 samples 容器中,samples 正好是一个 vector 容器。通过 back_insert_iterator 对象将这些元素添加到 samples,因此这个容器只包含从 measures中复制的元素。

  
  (4)remove_copy_if

  remove_copy_if() 的作用是基于remove_copy()之后,就像 remove_if() 之于 remove()
  
  关于remove_copy_if案例如下:


//==================5.3、remove_copy_ifint main(){using Name = pair<string, string>;set<Name> blackNames{ Name{ "Al", "Bedo" }, Name{ "Ann", "Ounce" }, Name{ "Jo","King" } };deque<Name> VIPNames{ Name{ "Stan", "Down" }, Name{ "Al", "Bedo" },Name{ "Dan", "Druff" }, Name{ "Di", "Gress" }, Name{ "Ann", "Ounce" },Name{ "Bea", "Gone" } };deque<Name> validated;cout << "VIPNames原序列:" << endl;for_each(begin(VIPNames), std::end(VIPNames), [](const Name& name) {std::cout << '"' << name.first << " " << name.second << "\" "; });cout << endl;remove_copy_if(begin(VIPNames), end(VIPNames), back_inserter(validated), [&blackNames](const Name& name) { return blackNames.count(name); });cout << "remove_copy_if后的VIPNames序列:" << endl;for_each(begin(VIPNames), std::end(VIPNames), [](const Name& name) {std::cout << '"' << name.first << " " << name.second << "\" "; });cout << endl;cout << "remove_copy_if后的validated序列:" << endl;for_each(begin(validated), std::end(validated), [](const Name& name) {std::cout << '"' << name.first << " " << name.second << "\" "; });cout << endl;return 0;

在这里插入图片描述
  这段代码实现了和之前remove_if()代码类似的功能,除了结果被保存在 validated 容器中和没有修改 VIPNames 容器之外。

  
  (5)unique

  unique() :可以在序列中原地移除重复的元素,这就要求被处理的序列必须是正向迭代器所指定的。在移除重复元素后,它会返回一个正向迭代器作为新序列的结束迭代器。可以提供一个函数对象作为可选的第三个参数,这个参数会定义一个用来代替 == 比较元素的方法。
  
  关于unique案例如下:

//==================5.4、uniqueint main() {vector<string> words{ "one", "two", "two", "three", "two", "two", "two" };auto end_iter = unique(begin(words), end(words));cout << "unique后的words序列:" << endl;copy(begin(words), end(words), ostream_iterator<string>{cout, " "});cout << endl;cout << "unique后的变化显示:" << endl;copy(begin(words), end_iter, ostream_iterator<string>{cout, " "});cout << endl;return 0;
}

在这里插入图片描述

  这段代码实现消除 words 中的连续元素。但是,没有元素会从输入序列中移除;算法并没有方法去移除元素,因为它并不知道它们的具体上下文。整个序列仍然存在。但是,无法保证新末尾之后的元素的状态;如果在上面的代码中用 end(words) 代替 end_iter 来输出结果就是:one two three two two two

  
  (6)unique_copy

  前面讲的unique()功能是去除相邻的重复元素(只保留一个)。但是它并不真正把重复的元素删除了,是把非重复的元素往前移动替换到重复的元素。
  而 unique_copy()功能是去除相邻的重复元素(只保留一个)的结果保留到第三个参数中(一般这是一个空容器)对原容器并不修改

  
  关于unique_copy案例如下:

//==================5.5、unique_copy
int main() {vector<int> nums = { 10, 5, 40, 10, 5, 20, 10, 10, 30 };sort(nums.begin(), nums.end());cout << "排序后num = " << endl;for (const auto &num : nums) {cout << num << " ";}cout << endl;vector<int> newNums;//nums排序后去重的结果保留容器unique_copy(nums.begin(), nums.end(), back_inserter(newNums));cout << "排序、去重后newNums = " << endl;for (const auto &num : newNums) {cout << num << " ";}cout << endl;return 0;
}

在这里插入图片描述


3、总结

  最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,我也会及时更新,来督促自己学习进度。一开始提及的博主【AI菌】,个人已关注,并订阅了相关专栏(对我有帮助的),希望大家觉得不错的可以点赞、关注、收藏。

相关文章:

嵌入式分享合集106

一、可控硅控制电路实例 可控硅是可控硅整流器的简称。可控硅有单向、双向、可关断和光控几种类型。它具有体积小、重量轻、效率高、寿命长、控制方便等优点&#xff0c;被广泛用于可控整流、调压、逆变以及无触点开关等各种自动控制和大功率的电能转换的场合。 单向可控硅是一…...

翻译文本的软件有哪些?这几个翻译工具你可以试试看

文本翻译&#xff0c;是我们在生活中或工作中比较常见的一个需求。例如有时收到一份英文资料&#xff0c;没时间逐字翻译成中文&#xff0c;那就需要借助翻译工具来帮忙了&#xff1b;或者是有时需要将一些内容翻译成英文&#xff0c;而碰巧遇到句子不知道如何翻译&#xff0c;…...

Android 通过Room操作SQLite数据库

谷歌推荐使用Room操作数据库&#xff0c;Room在 SQLite 上提供了一个抽象层&#xff0c;在充分利用 SQLite强大功能的同时&#xff0c;能够流畅地访问数据库。 Room的三个主要组件&#xff1a; 数据库类&#xff0c;用于保存数据库并作为应用持久性数据底层连接的主要访问点。…...

css--内外边距、 盒子模型、位置、浮动

一、内外边距 1.margin 1.1属性为给定元素设置所有四个&#xff08;上下左右&#xff09;方向的外边距属性。 上下左右具有四个方向:margin-top、margin-right、margin-bottom、margin-left可取值&#xff1a;length&#xff1a;固定值 percentage&#xff1a;相对于包…...

数据结构每日亿题(六)

文章目录一.用队列实现栈2.大概思路3.代码实现3.13.23.33.43.53.63.7二.用栈实现队列2.大概思路3.代码实现3.13.23.33.43.53.63.7三.结束一.用队列实现栈 原题传送门&#xff1a;力扣 题目&#xff1a;题目的意思是&#xff1a;给你两个队列&#xff0c;让你实现后入先出的操作…...

Java八股文

2022年接近年底了&#xff0c;想必绝大多数的小伙伴跳槽的心已经蠢蠢欲动。但一边又是互联网寒冬、大厂裁员&#xff0c;导致人心惶惶&#xff0c;想跳又不敢跳。但现在罡哥&#xff0c;给大家整理了八股文大厂面试真题和面试技巧。这里免费分享给大家。 资料包括&#xff1a;…...

自动化早已不是那个自动化了,谈一谈自动化测试现状和自我感受……

前言 从2017年6月开始接触自动化至今&#xff0c;已经有好几年了&#xff0c;从17年接触UI自动化&#xff08;unittestselenium&#xff09;到18年接触接口自动化&#xff08;unittestrequests&#xff09;再到18年自己编写自动化平台&#xff08;后台使用python的flask&#…...

蓝桥杯刷题(二)

蓝桥杯刷题一.空间二.排序三.成绩分析四.蛇形填数五.跑步锻炼&#xff08;较难&#xff09;一.空间 这道题很简单&#xff0c;要弄清单位间的转换和如何输出就可以啦 #include <stdio.h>int main() {printf("%.0f",256/(32/4/2/1024.0000/1024));return 0; }记…...

进程和线程详解

目录 前言&#xff1a; 操作系统定位 并发 并行 并发 进程 描述 PCB 管理 内存管理 进程间通信 线程 小结&#xff1a; 前言&#xff1a; 当一个程序运行起来时&#xff0c;操作系统要为之分配一些资源&#xff0c;这样的运行起来的程序称之为一个进程。为了有效解…...

flex blaze+java通信的例子

步骤&#xff1a; 1&#xff1a;建立java web程序 2&#xff1a; 下载blazeDS包&#xff0c;解压后将WEB-INF下的 flex&#xff0c;lib&#xff0c;web.xml复制到java程序的WEB-INF下 3&#xff1a;打开web.xml文件将以下代码的注释去掉&#xff0c;并修改 <param-value>…...

Allegro如何输出IDF文件操作指导

Allegro如何输出IDF文件操作指导 Allegro支持输出IDF文件,用于导入结构软件中检查和查看,具体操作如下 点击File-export-IDF 会弹出一个对话框,file name type选择IDF 然后点击export,输出IDF文件,文件已经输出 This section is describe what the function allegro h…...

生产工艺审批管理系统java项目开发jsp编程软件myeclipse开发Mysql数据库计算机网页

一、源码特点 JSP 生产工艺审批管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0…...

actionScript 数组去重

public function unique(array:Array):Array { for (var i:int0; i < array.length; i) { for (var j:inti 1; j < array.length; j) { //注意 if (array[i] array[j]) { array.splice(j, 1); j--; } } } return array…...

【C++音视频开发】初级篇 | RGB与YUV

前言 本专栏将不间断更新有关C音视频开发的内容&#xff0c;其中有初级篇、中级篇与高级篇的内容&#xff0c;包括但不限于音视频基础、FFmpeg实战、QT、流媒体客户端、流媒体服务器、WebRTC实战、Android NDK等等。是博主花了将近5000元购买的课程中的知识点&#xff0c;其中…...

Html-文本属性

常用的文本属性 属性描述说明font-size字体大小单位是px&#xff0c;浏览器默认是16px。font-family字体多个字体中间用逗号链接&#xff0c;先解析第1个字体,如果没有解析第2个字体,以此类推color颜色 red;#ff0;rgb(255,0,0); 0-255font-weight加粗 bolder(更粗的&#xff09…...

Dockerfile

Dockerfile指令集 对于Dockerfiel而言&#xff0c;是在学习docker工具里面&#xff0c;最重点的内容&#xff0c;它可以帮助我们生成自己想要的基础镜像。部署一个容器最重要的就是镜像&#xff0c;指令都已经内置好了。 FROM 这个镜像的妈妈是谁&#xff1f;&a…...

Java反射04:获取运行时类的属性结构及其内部结构

文章目录获取运行时类的属性结构及其内部结构新建测试类1.获取每一个Field&#xff08;属性&#xff09;2.获取运行时类的方法结构3.获取运行时类的构造器4.获取当前运行时所继承的父类和接口5.获取当前运行时类的注解、包、泛型获取运行时类的属性结构及其内部结构 通过反射获…...

双软企业认定需要什么条件

认定双软企业的好处 1、税收优惠:所得税两免三减半。双软认证企业&#xff0c;自获利年度起&#xff0c;第一年和第二年免征企业所得税&#xff0c;第三年至第五年减半征收企业所得税。 增值税超过3%的部分即征即退。 2、政策支持:各地政府对于科研专项资金、税收减免科技计划、…...

qsettings 读写注册表

qsettings简单的实现一个注册表读写操作&#xff0c;记录程序中需要保存的信息。使用qsettings声明对象之前&#xff0c;需要指明qsettings的组织名和应用名&#xff0c;分别利用QCoreApplication::setOrganizationName()和QCoreApplication::setApplicationName()来指定组织名…...

【JavaScript高级进阶】构造函数和原型,学会prototype

目录 前言 1.构造函数和原型 1.1使用prototype解决内存浪费的问题 1.2constructor构造函数构造器构造函数 2.原型链 2.1js中成员查找规则 2.2原型对象this指向 2.3扩展内置对象 3.call作用 4.继承 4.1利用原型对象继承 写在最后 前言 哈喽哈喽大家好&#xff0c;因为…...

VMware16虚拟机添加硬盘(磁盘)和挂载硬盘(磁盘)

记录&#xff1a;317 场景&#xff1a;在VMware16虚拟机&#xff0c;安装了CentOS 7.9操作系统场景下&#xff0c;添加硬盘(磁盘)和挂载硬盘(磁盘)。 版本&#xff1a; 操作系统&#xff1a;CentOS 7.9 1.机器配置 机器名称&#xff1a;B200&#xff1b;主机名称&#xff…...

【学生个人网页设计作品】使用HMTL制作一个超好看的保护海豚动物网页

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…...

短视频社交|电影点播平台Springboot+vue+ElementUI前后端分离

感谢您的关注&#xff0c;请收藏以免忘记&#xff0c;点赞以示鼓励&#xff0c;评论给以建议&#xff0c;爱你哟 项目编号&#xff1a;BS-PT-071 一&#xff0c;项目简介 本项目基于Springbootvue开发实现了一个电影点播和短视频分享平台&#xff0c;名为爱奇艺影视平台系统。…...

基于Springboot+mybatis+mysql+html图书管理系统

基于Springbootmybatismysqlhtml图书管理系统一、系统介绍二、功能展示1.用户登陆2.图书管理3.读者管理4.借还管理5.密码修改6.图书查询&#xff08;读者&#xff09;7.个人信息&#xff08;读者&#xff09;8.我的借还&#xff08;读者&#xff09;一、系统介绍 系统主要功能…...

【数据结构】第三章 栈和队列

1.单选(2分) ‏下列关于队列的叙述正确的是&#xff08; &#xff09;。 A.在队列中只能删除数据 B.队列是先进先出的线性表 C.队列是后进先出的线性表 D.在队列中只能插入数据 正确答案&#xff1a;B 2.单选(2分) ‌一个栈的输入序列为1&#xff0c;2&#xff0c;3&#xff0…...

公众号网课查题系统

公众号网课查题系统 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击…...

02 LaTex之小tips

1.运行 2.头&#xff0b;尾 \documentclass[11pt]{article}\usepackage{algorithm, algpseudocode} \usepackage{amsmath,amssymb,amsthm} \usepackage{mathrsfs}% huaxie zimu \textwidth 16cm\textheight 22cm\oddsidemargin0cm\evensidemargin\oddsidemargin\usepackage{un…...

使用kubeadm搭建高可用集群-k8s相关组件及1.16版本的安装部署

本文是向大家分享k8s相关组件及1.16版本的安装部署&#xff0c;它能够让大家初步了解k8s核心组件的原理及k8s的相关优势&#xff0c;有兴趣的同学可以部署安装下。 什么是kubernetes kubernetes是Google 开源的容器集群管理系统&#xff0c;是大规模容器应用编排系统&#xff…...

为了摸鱼,我开发了一个工具网站

&#x1f3e1; 博客首页&#xff1a;派 大 星 ⛳️ 欢迎关注 &#x1f433; 点赞 &#x1f392; 收藏 ✏️ 留言 &#x1f3a2; 本文由派大星原创编撰 &#x1f6a7; 系列专栏&#xff1a;《开源专栏》 &#x1f388; 本系列主要输出作者自创的开源项目 &#x1f517; 作品&…...

CodeForces - 545E Paths and Trees 最短路建树

题目链接&#xff1a;点击查看 Little girl Susie accidentally found her elder brothers notebook. She has many things to do, more important than solving problems, but she found this problem too interesting, so she wanted to know its solution and decided to a…...

koa + pug模板引擎

模板引擎 模板引擎&#xff1a;模板引擎是web应用中动态生成html的工具&#xff0c;负责将数据和模板结合。常见模板引擎有&#xff1a;ejs、jade&#xff08;现更名为pug&#xff09;、Handlebars、Nunjucks、Swig等&#xff1b;使用模板引擎可以是项目结构更加清晰&#xff…...

数字集成电路设计(二、Verilog HDL基础知识)

文章目录1. 语言要素1.1 空白符1.2 注释符1.3 标识符1.3.1 转义标识符1.4 关键字1.5 数值1.5.1 整数及其表示方式1.5.2 实数及其表示方式1.5.3 字符串及其表示方式2. 数据类型2.1 物理数据类型2.1.1 连线型2.1.2 寄存器型2.2 连线型和寄存器型数据类型的声明2.2.1 连线型数据类…...

蓝桥杯刷题(三)

蓝桥杯刷题一.等差素数列&#xff08;较难&#xff09;二.货物摆放&#xff08;思路新奇&#xff09;三.既约分数四.跳跃五.数值求值&#xff08;坑题&#xff09;蓝桥杯题库一.等差素数列&#xff08;较难&#xff09; 这道题有公式&#xff0c;其等差就是它长度内所有素数的乘…...

【工具使用】Visual Studio Code远程调试

VS Code的其中一个关键的特征就是它极好的调试支持。VS Code的内置调试器帮助加速你的编辑、编译和调试循环。 调试扩展 VS Code有Node.js运行的内置的调试支持&#xff0c;并且能够调试Java脚本或者任何其他可以转译为JavaScript的语言。为了调试其他语言&#xff08;包括P…...

【Flutter】【widget】Table 表格widget

文章目录前言一、Table 是什么&#xff1f;二、使用步骤1.Table 基础使用2.宽度3.设置边框4.TableCell设置单元格式widget等其他设置总结前言 Table 表格widget&#xff0c;其实很少使用到的&#xff0c;等有需要的时候在查看该widget 一、Table 是什么&#xff1f; 表格widg…...

ADB学习笔记

简介&#xff1a; ADB的全称为Android Debug Bridge&#xff08;调试桥&#xff09;&#xff0c; 它是一个客户端-服务器端程序&#xff0c;其中客户端是你用来操作的电脑, 服务器端是android设备。作用显而易见&#xff0c;能方便我们在PC上对手机进行调试的一些工作。 原理…...

http load介绍

前几天工作中要对项目的接口做简单压测&#xff0c;就使用了http load做了简单测试&#xff0c;下面介绍一下这款工具的使用说明。简介&#xff1a;http_load是基于linux平台的性能测试工具&#xff0c;它体积非常小&#xff0c;仅100KB。它以并行复用的方式运行&#xff0c;可…...

DPDK之PMD原理

PMD是Poll Mode Driver的缩写&#xff0c;即基于用户态的轮询机制的驱动。本文将介绍PMD的基本原理。 在不考虑vfio的情况下&#xff0c;PMD的结构图如下&#xff1a; 图1. PMD结构图 虽然PMD是在用户态实现设备驱动&#xff0c;但还是依赖于内核提供的策略。其中uio模块&…...

Linux shell脚本之回顾及实用笔记

一、前言 我们从事运维的小伙伴,除了自动化运维外,在没有自动化条件下,借助shell脚本/Python脚本来提升运维效率,无疑是一个必选项,当前也可以自建自动化运维平台,我们这里还是以Linux shell脚本为主,来汇总一些常用的运维脚本,对于有基础的同学,也随本文一起回顾下相…...

TestNG使用总结

TestNG简介&#xff1a; TestNG是一个测试框架&#xff0c;其灵感来自JUnit和NUnit&#xff0c;但同时引入了一些新的功能&#xff0c;使其功能更强大&#xff0c;使用更方便。 TestNG相较于Junit的优点&#xff1a; 可指定执行顺序&#xff0c; dependsOnMethods 属性来应对…...

面向对象编程的弊端

英文原文&#xff1a;What’s Wrong with OOP and FP 我不理解为什么人们会对面向对象编程和函数式编程做无休无止的争论。就好象这类问题已经超越了人类智力极限&#xff0c;所以你可以几个世纪的这样讨论下去。经过这些年对编程语言的研究&#xff0c;我已经清楚的看到了问题…...

5.Servlet

一、Servlet快速入门 1.创建web项目&#xff0c;导入Servlet依赖坐标&#xff08;scope范围为provided因为上传后tomcat也有这个&#xff0c;可能会冲突&#xff09;pom.xml <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-a…...

(续)SSM整合之springmvc笔记(@RequestMapping注解)(P124-130)还没完

RequestMapping注解 一.准备工作 1 新建spring_mvc_demo com.atguigu 2. 导入依赖 <packaging>war</packaging><dependencies><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>sprin…...

c++入门必学算法 质数筛

文章目录一、什么是质数筛二、暴力枚举1、暴力枚举基本思想&#xff1a;2、模板代码3、运行结果三、埃氏筛1、埃氏筛基本思想&#xff1a;2、模板代码3、运行结果四、欧拉筛1、对比埃氏筛2、欧拉筛的基本思想3、模板代码3、运行结果五、总结一、什么是质数筛 质数筛也叫素数筛…...

适用于C/C++开发人员的HOOPS

1.编译和运行时信息 1.1编制和执行 编译和运行基于C的应用程序需要以下步骤&#xff1a; 编译&#xff1a; 所有3DGS应用: hoops.lib 使用HOOPS/MVO的应用: hoops_mvo.lib 使用HOOPS/Stream的应用: hoops_stream.lib 执行&#xff1a;确保以下本地DLL位于应用程序的目录或…...

Verilog结构语句和函数、任务语句

目录 结构说明语句 initial说明语句 always说明语句 task和function说明语句 task说明语句 function说明语句 关于使用任务和函数的小结 结构说明语句 Verilog语言中的任何过程模块都从属于以下4种结构的说明语句&#xff1a; initial说明语句 一个模块种可以有多个i…...

String 创建字符串对象和字符串常量池的联系推理

文章目录String 创建字符串对象和字符串常量池的联系推理ref前提intern方法String s "abc";字符串相加String 创建字符串对象和字符串常量池的联系推理 可能有错误理解 ref String s1 new String(“abc”);这句话创建了几个字符串对象&#xff1f; 我提的issue …...

flex 计算指定日期是本年度第几周

/** * 计算指定日期是本年度第几周 *传日年月日&#xff0c;返回number */ private function weekOfYear(yyyy:Number,mm:Number,dd:Number):Number{ var myDate:Date new Date(yyyy, mm - 1, dd); var startDate:Date new Date(yyyy,0,1); v…...

SpringCloud Zuul(四)之工作原理

一、筛选器概述 Zuul的中心是一系列过滤器&#xff0c;这些过滤器能够在HTTP请求和响应的路由期间执行一系列操作。 以下是Zuul过滤器的主要特征&#xff1a; 类型&#xff1a;通常定义路由流程中应用过滤器的阶段&#xff08;尽管它可以是任何自定义字符串&#xff09;执行…...

【毕业设计】大数据分析的航空公司客户价值分析 - python

文章目录0 前言1 数据分析背景2 分析策略2.1 航空公司客户价值分析的LRFMC模型2.2 数据2.3 分析模型3 开始分析3.1 数据预处理3.1.1 数据预览3.1.2 数据清洗3.2 变量构建3.3 建模分析4 数据分析结论4.1 整体结论4.2 重要保持客户4.3 重要挽留客户4.4 一般客户与低价值客户5 最后…...