C++ 集合

一:基本知识

1。 标准库类型

       C++定义的基本数据类型有字符型,整数型,浮点型。存储空间以机器而定(这是与java的区别),但它对特定的机器来说,长度是确定的。

        标准库类型是高级抽象数据类型,包括可变长度的string,vector。string由标准库负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库string类型的目的就是满足对字符串的一般应用。(C语言里有<string.h>这个头文件,但是C语言里没有string 这个类型,不能通过下面这种形式来声明string的变量 string aString; 它是通不过编译的,因为C语言里压根就没有string这个类型,所以字符串都是通过char数组来存储的,而<string.h>这个头文件里声明的函数原型也全是针对char数组的种种操作,所以这些的参数类型和返回类型都是字符指针,没有字符串指针的形式,如char *strncpy(char* dest, char* src) 。直到C++中才出现了string这个类(注意是类,不是类型),呵呵)。所以string的初始化也应该调用它的构造函数,尽量不要像基本数据类型那样赋值(虽然这样做是没有问题)。计算string长度用size()函数,而以前的strlen(char *)函数的参数是字符指针,sizeof是运算符。string的size()执行结果为了避免溢出,最安全的做法是用 string::size_type类型,不要直接用int(虽然大部分情况不会出现问题)。 string相加没有问题,但当他们与字符串字面值相加时必须保证"+"号两边有一个string类型的,否则不能相加。可用下标操作符取出string 中的每个字符,就相当于数组操作。

        vector不是一种数据类型,而只是一个类模板,可用来定义任意多种数据类型。vector类型的每一种都指定了其保存元素的类型。vector的下标操作只能用于获取已存在的元素,不能向vector中添加元素。并且仅能对已经存在的元素进行下标操作。C++里不是所有的容器都支持下标操作,但他们都定义了自己的迭代器(iterator),用于检查容器内元素并遍历容器元素。

       标准库bitset类型也是一种类模板,只需指定他的长度即可。

       修改已有类型形成的复合类型。

2。低级数据抽象类型-数组,指针,他们是C++内置数据类型。


二:容器和算法

       C++提供了使用抽象进行高效率编程的方式。标准库就是一个很好的例子:标准库定义了许多容器类以及一系列泛型算法,是程序员可以更简洁、抽象和有效地编写程序。这样可以让标准库操心那些繁琐地细节,特别是内存管理,我们地程序只需关注要解决地实际问题就行了。string类型可以当作只包含字符地特殊容器。泛型算法中,所谓“泛型(generic)”指的是两个方面:这些算法可作用于各种不同的容器类型,而这些容器又可以容纳多种不同类型的元素。

       STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack> 和<utility>。容器就是数据结构,存放数据的地方,而迭代器提供了访问容器的接口,再加上算法就可以构建高效的应用程序了。为不同的容器类型提供了通用接口,容器的操作和算法也是一直定义的。

1。顺序容器。顺序容器内的元素按其位置存储来访问。

    (1)vector 支持快速随即访问。Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。

      当不使用默认构造函数,而是用其他构造函数初始化顺序容器时,必须指出该容器有多少个元素,并提供这些元素的初值,同时指定元素个数和初值的一个方法是将新创建的容器初始化为一个同类型的已存在容器的副本:                                                                               

                      vector<int> ivec; //调用了默认构造函数

                      vector<int> ivec2(ivec)   //利用已经存在的容器ivec初始化

       我们不能直接将一种容器内的元素复制给另一个容器,但系统允许通过传递一对迭代器间接实现该功能。使用迭代器时,不要求容器类型相同。

       由于受容器元素类型的约束,所以可定义元素是容器类型的容器。例如,可以定义vector类型的容器lines,其元素为string类型的vector 对象:vector< vector<string> > lines;   //vector of vectors,注意,必须用空格隔开两个相邻的>符号,以示这是两个分开的符号,否则,系统会认为>>是单个符号,为右移操作符,并导致编译时错误。

       常用迭代器运算(所有迭代器的公用接口)

*iter 解引用

iter->mem 获取指定元素中名为mem的成员,等价与(*iter).mem

++iter,iter++,--iter,iter--   迭代器自加自减运算,实际是容器位置的加减运算,不是容器的值

iter1==iter2,iter1!=iter2   比较两个迭代器是否相等,即是否指向同一个位置或者指向同一个容器的超出末端的下一个位置。

       vector和deque容器的迭代器提供的额外运算,包括算术运算和比较运算。这是因为只有这两种容器为其元素提供快速随机的访问。他们确保可根据元素位置直接有效地访问指定的容器元素。这两种容器都支持通过元素位置实现的随即访问,因此他们的迭代器可以有效地实现算术和关系运算。他们只能是同种类型的类型的容器(里面的元素类型也相同)进行比较,实际比较的也是容器里元素的关系运算。

     (2)list 支持快速插入/删除。list虽然也叫做顺序容器,只是表示我们对他的访问可以按顺序来,但他的内存分配形式是不连续的,只有vector的内存分配是连续分配的。List将元素按顺序储存在链表中. 与 向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢.

      (3) deque 双端队列,双向队列和vector很相似,但是它允许在容器头部快速插入和删除(就像在尾部一样)。

       由于迭代器可能指向超出容器末端的下一个位置,这是一个不存在元素的位置,因此insert()函数是在其指向位置之前而非其后插入元素;就像表示迭代器范围时,用的是左闭合区间,这样当begin!=end时,始终能保证至少有一个元素(即begin指向的元素)。

       string除了基本的字符串操作,还支持大多数顺序容器操作,在某些方面可以把string当作字符容器。

       以下为顺序容器适配器,适配器(adaptor)是标准库中通用的概念,包括容器适配器、迭代器适配器和函数适配器。本质上,适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。例如,stack(栈)适配器可使任何一种顺序容器以栈的方式工作。

       适配器的初始化有两种形式,当调用默认构造函数时用于创建空对象,而带一个容器参数时的构造函数则将参数容器的副本作为其基础值。如:stack<int> stk; //空栈 stack<int> stk(deq);(deque<int> deq)//带参

       默认的stack和queue都是基于deque容器实现,而 priority_queue则在vector容器上实现。在创建适配器时,通过将一个顺序容器指定为适配器的第二个类型参数,可覆盖其关联的基础容器类型。对于给定的适配器,其关联的容器必须满足一定的约束条件。stack适配器所关联的基础容器可以是任意一种顺序容器类型。因此,stack栈可以建立在vector,list或者deque容器之上。而queue适配器要求其关联的基础容器必须提供push_front运算,因此只能建立list容器上,而不能建立在vector容器上。priority_queue适配器要求提供随机访问功能,因此建立在vector或deque容器上,但不能建立在list容器上。

       (4) stack 后进先出(LIFO)栈。它提供了五种操作empty(),size(),pop(),top(),push()。栈适配器默认是建立在deque容器上,因此采用deque提供的操作来实现栈功能的,比如他的push()函数就是通过调用deque的push_back()操作实现的,但程序员不能直接访问deque所提供的操作,即不能在栈上调用push_back函数。

     (5) queue 先进先出(FIFO)队列

     (6) priority_queue 有优先管理的队列

2。关联容器,其元素按键(key)排序。关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素(但顺序容器中的元素并不一定是顺序存放在内存中的)。关联容器支持通过键来高效地查找和读取元素,所以处理检索方面地问题时,数据结构考虑用关联容器,处理遍历、删除、添加的就用顺序容器。

       set和map类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素。如果一个建必须对应多个实例,则需使用multimap或 multiset类型,这两种类型允许许多个元素拥有相同的键。关联容器支持很多顺序容器提供的相同操作,此外,它自己还有管理或使用键的特殊操作。

       标准库类型-pair类型,该类型在utility头文件中定义。pair对象在创建时,必须提供两个类型名:pair对象所包含的两个数据成员各自对应的类型名字,这两个类型不必相同。与其他标准库类型不同(比如容器是通过迭代器来访问容器的数据元素),对于pair类,可以直接访问其数据成员:其成员都是共有的,分别命名为first和second,只需使用普通的点操作符-成员访问标志即可访问其成员。

       关联容器不提供front、back、push_front、push_back、pop_front、pop_back.“容器元素根据键的次序排列” 这一事实就是一个重要的结论:在迭代遍历关联容器时,我们可确保按键的顺序访问元素,而与元素在容器中的存放位置完全无关。

(1)map:在学习map的接口时,需谨记value_type是pair类型,它的值成员可以修改,但键成员不能修改。

         在添加新的map元素时,使用insert成员可避免使用下标操作符所带来的副作用:不必要的初始化。

         遍历map容器时是按字典序遍历的,不是按照插入pair对的先后,迭代器自增时,下一个指向的也是字典序升高的紧挨着的那个。

(2)set

      map容器是键-值对的集合,好比以人名为键的地址和电话号码。相反地,set容器只是单纯键地集合。当只想知道一个值是否存在时,使用set容器是最适合的。

       set<string> set1;

       set1.insert("the");

       set<string> set2;

       set2.insert(ivec.begin(),ivec.end());

       与map容器的操作一样,带有一个键参数的insert版本返回pair类型对象,包含一个迭代器和一个bool值,迭代器指向拥有该键的元素,而bool值表明是否添加了元素。使用迭代器对的insert版本返回void类型

       set容器不提供下标操作符。为了通过键从set中获取元素,可使用find运算。如果只需要简单地判断某个元素是否存在,同样可以使用count运算,返回set中该键对应的元素个数。

(3)multimap、multiset

         在multimap和multiset容器中,如果某个键对应多个实例,则这些实例在容器中将相邻存放。

3。泛型算法。

        标准容器定义了很少的操作。大部分容器都支持添加和删除元素;访问第一个和最后一个元素;获取容器的大小,并在某些情况下重设容器的大小;以及获取指向第一个和最后一个元素的下一位置的迭代器。可以想象,用户可能还希望对容器元素进行更多其他有用操作:也许需要给顺序容器排序,或者查找某个特定的元素,或者查找最大或最小的元素,等等。标准库并没有为每种容器类型都定义实现这些操作的成员函数,而是定义了一组泛型算法(generic algorithm):因为他们实现共同的操作,所以称之为"算法";而“泛型”指的是他们可以操作在多种容器类型上-不但可以作用于vector或 list这些标准库类型,还可用在内置数组类型、甚至其他类型的序列上。

       大多数算法是通过遍历由两个迭代器标记的一段元素来实现其功能。典型情况下,算法在遍历一段元素范围时,操纵其中的每一个元素,算法通过迭代器访问元素,这些迭代器标记了要遍历的元素范围。

       这些算法从不使用容器操作,因而其实现与类型无关,元素的所有访问和遍历都通过迭代器实现(这是算法能泛型的根本原理)。实际的容器类型未知(甚至所处理的元素是否存在在容器中也是未知的)。标准库提供了超过100种算法。与容器一样,算法有着一致的结构。比起死记全部一百种算法,了解算法的设计可使我们更容易学习和使用他们。

        泛型算法本身从不执行容器操作,只是单独依赖迭代器和迭代器操作实现。算法基于迭代器及其操作实现,而并非基于容器操作。这个事实也许比较意外,但本质上暗示了:使用“普通”的迭代器时,算法从不修改基础容器的大小。正如我们所看到的,算法也许会改变存储在容器中的元素的值,也许会在容器内移动元素,但是,算法从不直接添加或删除元素。但标准库提供了另一种特殊的迭代器类:插入器(inserter),除了用于遍历其所绑定的序列之外,还可实现更多的功能。在给这类迭代器赋值时,在基础容器上将执行插入运算。如果算法操纵这类容器,迭代器将可能导致在容器中添加元素。但是算法本身从不这么做。

类属算法:

类属算法分为1、非可变序列(只读)算法

                         2、可变序列(写容器元素)算法 

                         3、排序相关算法

                         4、通用数值算法

1、非可变序列算法:指不直接修改其所操作的容器内容的算法。       find : Locates the position of the first occurrence of an element in a range that has a specified value.(查找序列中第一个出现的给定值的位置)。它的判断函数的形式是 find_if : 查找序列中第一个使给定的判断函数返回真的元素。find和find_if具有线性时间复杂度。        adjacent_find : Searches for two adjacent elements that are either equal or satisfy a specified condition.(查找在序列中相邻且相等或者满足指定条件的两个元素)此算法返回指向两个元素中第一个元素的迭代器。adjacent_find具有线性时间复杂度。        count : Counts the number of elements in the range [ First, Last+1) that match Valueand returns the number of matching elements.(计算[First,Last+1)区间内与Value相匹配的对象的数目并作为返回值返回(相匹配元素的个数))。它的一元判断函数形式是 count_if : 满足给定条件的元素的个数。count和count_if具有线性时间复杂度。        for_each : Applies a specified function object to each element in a forward order within a range and returns the function object.对序列中指定范围内的每个元素施加由指定函数指定的操作。返回函数对象拷贝。for_each具有线性时间复杂度。        mismatch : Compares two ranges element by element either for equality or equivalent in a sense specified by a binary predicate and locates the first position where a difference occurs.比较容器中两个区间的元素。返回位置。详见书p63。具有线性时间复杂度。        equal : Compares two ranges element by element either for equality or equivalence in a sense specified by a binary predicate.比较容器中两个区间的元素。返回真或假。详见书p63。具有线性时间复杂度。         search : Searches for the first occurrence of a sequence within a target range whose elements are equal to those in a given sequence of elements or whose elements are equivalent in a sense specified by a binary predicate to the elements in the given sequence. 给定两个迭代器区间,将后一个区间内的对象作为一个子序列,并在前一个区间内查找出现该子序列的第1个位置。它是对字符串匹配函数的推广,比如C的库函数 strstr。--------------------------------------------------------------------------------------------2、可变序列算法:可以修改它们所操作的容器内容的算法。            copy : Assigns the values of elements from a source range to a destination range, iterating through the source sequence of elements and assigning them new positions in a forward direction.将容器中的元素从一个区间复制到另一个区间。copy(first1, last1, first2) 进行的是前向处理。           copy_backward : Assigns the values of elements from a source range to a destination range, iterating through the source sequence of elements and assigning them new positions in a backward direction.同  copy,copy_backward(first1, last1, last2)。但是进行的是后向处理。           fill : Assigns the same new value to every element in a specified range. 把某个值复制到某一区间的所有位置中。fill(first, last, value)把value的last-first个副本放入区间[first, last)中。fill_n(first, n, value)把value的n个副本放到区间[first, first+n)中。           generate : Assigns the values generated by a function object to each element in a range.连续调用gen函数(该函数时generate算法的第三个参数)last-first次,并用该函数的这些返回值来填充区间 [first,last)。这里假定gen是不带参数的函数。具有线性时间复杂度。           partition : Classifies elements in a range into two disjoint sets, with those elements satisfying a unary predicate preceding those that fail to satisfy it.对于给定的区间[first,last)和一个一元判断函数pred,类属算法partition可以对该区间内的元素重新排列,以使所有满足判断函数pred的元素排在所有不满足pred的元素前面。该算法还有一个版本stable_partition,能保证分割后的每一组中元素的相对位置保持不变。它们的返回值都是一个迭代器,该迭代器代表第一组数据的结尾,同时也是第二组数据的开头。都具有线性时间复杂度。           random_shuffle : Rearranges a sequence of N elements in a range into one of N! possible arrangements selected at random.利用能够产生伪随机数的函数,对区间[first,last)中的元素混洗顺序后重新排列。产生的排列结果近似于均匀分布。还有一种形式:有3个参数,其中第3个参数是一个函数,通过该函数,可以为算法提供不同的随机数发生器。这个随机数发生器函数的参数是一个整数N,其返回值是在区间 [0,N)内随机选取的整数。具有线性时间复杂度。          remove : Eliminates a specified value from a given range without disturbing the order of the remaining elements and returning the end of a new range free of the specified value.从一个区间中删除所有等于某个特定值的元素。该算法是稳定的,它可以保持从序列中删除元素后剩下元素之间的相对位置不变。remove并不改变它操作的容器大小。remove算法也有复制形式和判断函数形式。该算法的所有形式都具有线性时间复杂度。replace : Examines each element in a range and replaces it if it matches a specified value.把一个区间中所有等于某个特定值得元素用另一个值替换。replace算法也有复制形式和判断函数形式。该算法的所有形式都具有线性时间复杂度。          reverse : Reverses the order of the elements within a range.倒转一个区间中元素的排列顺序。用来指定区间的迭代器必须是双向迭代器。具有线性时间复杂度。          rotate : Exchanges the elements in two adjacent ranges.对区间内的元素进行循环移位操作。rotate(first, middle, last)表示将区间[first, last)内的元素循环左移middle-first个位置。函数返回后,原来区间[middle,last)中的元素将出现在区间 [first,first+k)中,其中k=last-middle;而原来在区间[first,middle)中的元素将出现在区间 [first+k,last)中。rotate算法的参数必须是双向迭代器。具有线性时间复杂度。          swap : Exchanges the values of the elements between two types of objects, assigning the contents of the first object to the second object and the contents of the second to the first.对两个值进行交换。具有常量的时间复杂度。          swap_ranges : Exchanges the elements of one range with the elements of another, equal sized range.交换两个区间中的值,而且这两个区间可以在不同的容器中。swap_ranges(first1, last1, first2)此语句将区间[first1,last1)和区间[first2,first2+N)中的内容相互交换,其中N=last1- first1。这两个区间不可以重叠。          transform : Applies a specified function object to each element in a source range or to a pair of elements from two source ranges and copies the return values of the function object into a destination range.将某个函数作用到某一区间内的每个元素上,并将该函数所返回的结果保存到另一个区间中。该算法有两种形式:一种采用的是一元函数,作用到区间中的每个元素上;另一种采用的是二元函数,同时作用到两个区间中相互对应的元素上。         unique : Removes duplicate elements that are adjacent to each other in a specified range.从输入序列中去掉所有相邻的重复元素。如果序列中的某个元素与其左面的相邻元素相等,则称该元素为相邻重复元素(注意,这里的相邻重复元素不是指两个相邻且相等的元素,而是指两个或两个以上相邻且相等的元素中除最左边元素以外的那些元素)。unique算法并不改变它操作的容器的大小,而只是把相邻重复元素之外的其他元素复制到一个较小的区间中,并返回指向该区间末尾的迭代器。具有线性时间复杂度。--------------------------------------------------------------------------------------------3、排序相关算法:包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。          sort : 对随机访问序列排序,排序结果仍然保存在操作的容器中。需要对数的额外存储空间。不要求是稳定的。就是说算法不需要保持相等元素的相对位置。          stable_sort : 对随机访问序列排序,排序结果仍然保存在操作的容器中。需要线性的额外存储空间。要求是稳定的。         partial_sort : 对随机访问序列排序,排序结果仍然保存在操作的容器中。所需要的额外存储空间是常量。不要求是稳定的。         nth_element : 在序列的第N个位置存放一个元素,该位置和该元素所满足的条件是:如果序列是有序的,则该元素就应处于该位置。此外,nth_element算法还对序列实现了分割,即所有第N个元素左边的元素都小于或等于其右边的元素。         binary_search、lower_bound、upper_bound、equal_range : 采用传统的二分查找方法在有序序列中查找元素.对于给定的有序区间[first,last)和元素x,如果在该区间中存在某个元素等于x,则类属算法 binary_search返回真,否则返回假。lower_bound和upper_bound算法的输入和binary_search算法的输入相同,但它们各返回一个迭代器i,这两个迭代器指向的位置分别表示在保持序列有序的情况下,可以向序列中插入元素x的第1个和最后一个位置(注意,不管区间中是否已存在等于x的元素,上面的定义都可以决定x在区间中的位置)。equal_range算法的返回值是两个迭代器,它们和lower_bound和 upper_bound所返回的一对迭代器是一样的。          merge : 合并两个有序区间,并把结果保存到另一个和两个输入区间均不重叠的区间中。inplace_merge算法的作用是合并两个相邻的有序区间,并用合并后的序列代替两个输入区间中原来的序列。集合操作和有序结构:
           includes : 检查区间[first1,last1)中的元素是否包含在另一个区间[first2,last2)中,并根据结果返回一个布尔值。
set_union : 对于给定的两个代表集合的区间[first1,last1)和[first2,last2),生成这两个集合的并集,其结果保存在区间[result,last)中,并返回last,即结果序列的尾后继值迭代器。
set_intersection : 得到两个输入序列的交集。
set_difference : 得到一个集合,该集合中的元素属于第1个区间,但不属于第2个区间。
set_symmetric_difference : 得到一个集合,该集合中的元素仅属于两个输入序列中的一个,而不包括两个输入区间的交集中的元素。和set_union算法一样,所有这些集合操作算法也把结果保存在区间[result,last)中,并且返回结果序列的尾后继值迭代器last.
堆操作:
堆代表了对随机访问数据结构的一种特殊组织方式。给定一个区间[first,last),如果满足下面两个特点,则称该区间为一个堆:
* first所指向的元素是区间中的最大元素。
* 可以通过pop操作删除first所指向的元素,也可以通过push操作向序列中插入元素。这两种操作的时间复杂度都是对数的,而且pop和push操作所返回的仍然为一个堆。
make_heap : 利用区间[first,last)中的元素构造一个堆,并把结果保存在区间[first,last)中。
pop_heap : 假定区间[first,last)中已经包含了一个堆,该算法的作用是将first位置上的值和last-1位置上的值交换,然后把区间[first,last-1)调整为一个堆。
push_heap : 假定区间[first,last-1)中已经包含了一个堆,该算法的作用是把区间[first,last)再重新调整为一个堆(从而把last-1位置上的元素压入堆中)。
sort_heap : 对存储在堆中的元素进行排序。
最小值和最大值:
min : 以两个元素作为参数,返回两个元素中较小的元素。min_element返回指向输入序列中最小元素的迭代器。
max : 以两个元素作为参数,返回两个元素中较大的元素。max_element返回指向输入序列中最大元素的迭代器。
词典序比较:
lexicographical_compare : 用下面两个方法对两个输入序列进行排序 : 首先,该算法比较两个序列中的对应元素e1和e2(分别来自序列1和序列2)。如果e1<e2,则算法立即返回,返回值为真;如果 e2<e1,则算法也立即返回,返回值为假;否则继续对下一对元素进行比较。如果已到达第1个序列的末尾,但没有到达第2个序列的末尾,则算法返回,返回值为真;否则返回假。定义在序列元素上的<运算符必须是严格弱序(也可以将定义为严格弱序的比较对象作为参数传递给 lexicographical_compare)。如果<或比较对象所定义的比较关系是一个严格全序,则由 lexicographical_compare所决定的比较关系也是一个严格全序;否则,该比较关系是严格弱序。
排列生成器:
next_permutation : 按词典序将序列变换为下一个排列。输入序列必须支持双向迭代器。
prev_permutation : 按词典序将序列变换为前一个排列。输入序列必须支持双向迭代器。--------------------------------------------------------------------------------------------4、通用数值算法:accumulate : 计算给定区间中值的累加和。partial_sum : 对于给定的序列x0,x1,...,x(n-1),计算和的序列x0,x0+x1,x0+x1+x2,...+x(n-1)。该算法可以把这些部分和保存在原序列中,也可以保存在另一个区间中。adjacent_difference : 对于给定的序列x0,x1,...,x(n-1),计算序列中相邻两个元素的差序列x1-x0,x2-x1,...,x(n-1)-x(n-2)。该算法可以把结果序列保存在原序列中,也可以保存在另一个区间中。inner_product : 计算两个输入序列的内积(inner product)。在下面的示例程序中,首先使用通常的基于+和*运算的内积定义计算了序列1,2,3,4,5和2,3,4,5,6的内积。即:1*2+2*3+3*4+4*5+5*6==70。默认情况下,inner_product算法使用+和*运算符。但是通过把函数对象作为参数传递给 inner_product,也可以使用其它运算符。

转载于:https://my.oschina.net/leoson/blog/103268

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值