C++/C++11中std::list双向链表的使用
std::list是双向链表,是一个允许在序列中任何一处位置以常量耗时插入或删除元素且可以双向迭代的顺序容器。std::list中的每个元素保存了定位前一个元素及后一个元素的信息,允许在任何一处位置以常量耗时进行插入或删除操作,但不能进行直接随机访问。
std::list和std::forward_list两个容器的设计目的是令容器任何位置的添加和删除操作都很快速。作为代价,这两个容器不支持元素的随机访问:为了访问一个元素,我们只能遍历整个容器。而且与vector、deque和array相比,这两个容器的额外内存开销也很大。
std::list与std::forward_list相比,它提供双向迭代的能力,但具有更低的空间效率。
Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions.
List containers are implemented as doubly-linked lists; Doubly linked lists can store each of the elements they contain in different and unrelated storage locations. The ordering is kept internally by the association to each element of a link to the element preceding it and a link to the element following it.
They are very similar to forward_list: The main difference being that forward_list objects are single-linked lists, and thus they can only be iterated forwards, in exchange for being somewhat smaller and more efficient.
Compared to other base standard sequence containers (array, vector and deque), lists perform generally better in inserting, extracting and moving elements in any position within the container for which an iterator has already been obtained,and therefore also in algorithms that make intensive use of these, like sorting algorithms.
The main drawback of lists and forward_lists compared to these other sequence containers is that they lack direct access to the elements by their position.
一个容器就是一些特定类型对象的集合。顺序容器(sequential container)为程序员提供了控制元素存储和访问顺序的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。
标准库中的顺序容器包括:
(1)、vector:可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢。
(2)、deque:双端队列。支持快速随机访问。在头尾位置插入/删除速度很快。
(3)、list:双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快。
(4)、forward_list:单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快。
(5)、array:固定大小数组。支持快速随机访问。不能添加或删除元素。
(6)、string:与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除速度快。
除了固定大小的array外,其它容器都提供高效、灵活的内存管理。我们可以添加和删除元素,扩张和收缩容器的大小。容器保存元素的策略对容器操作的效率有着固定的,有时是重大的影响。在某些情况下,存储策略还会影响特定容器是否支持特定操作。
例如,string和vector将元素保存在连续的内存空间中。由于元素是连续存储的,由元素的下标来计算其地址是非常快速的。但是,在这两种容器的中间位置添加或删除元素就会非常耗时:在一次插入或删除操作后,需要移动插入/删除位置之后的所有元素,来保持连续存储。而且,添加一个元素有时可能还需要分配额外的存储空间。在这种情况下,每个元素都必须移动到新的存储空间中。
list和forward_list两个容器的设计目的是令容器任何位置的添加和删除操作都很快速。作为代价,这两个容器不支持元素的随机访问:为了访问一个元素,我们只能遍历整个容器。而且,与vector、deque和array相比,这两个容器的额外内存开销也很大。
deque是一个更为复杂的数据结构。与string和vector类似,deque支持快速的随机访问。与string和vector一样,在deque的中间位置添加或删除元素的代价(可能)很高。但是,在deque的两端添加或删除元素都是很快的,与list或forward_list添加删除元素的速度相当。
forward_list和array是新C++标准增加的类型。与内置数组相比,array是一个种更安全、更容易使用的数组类型。与内置数组类似,array对象的大小是固定的。因此,array不支持添加和删除元素以及改变容器大小的操作。forward_list的设计目标是达到与最好的手写的单向链表数据结构相当的性能。因此,forward_list没有size操作,因为保存或计算其大小就会比手写链表多出额外的开销。对其他容器而言,size保证是一个快速的常量时间的操作。
通常,使用vector是最好的选择,除法你有很好的理由选择其他容器。
以下是一些选择容器的基本原则:
(1)、除法你有很好的理由选择其他容器,否则应该使用vector;
(2)、如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用list或forward_list;
(3)、如果程序要求随机访问元素,应使用vector或deque;
(4)、如果程序要求在容器的中间插入或删除元素,应使用list或forward_list;
(5)、如果程序需要在头尾位置插入或删除元素,但不会在中间位置进行插入或删除操作,则使用deque;
(6)、如果程序只有在读取输入时才需要在容器中间位置插入元素,随后需要随机访问元素,则:首先,确定是否真的需要在容器中间位置添加元素。当处理输入数据时,通常可以很容器地向vector追加数据,然后再调用标准库的sort函数来重排容器中的元素,从而避免在中间位置添加元素。如果必须在中间位置插入元素,考虑在输入阶段使用list,一旦输入完成,将list中的内容拷贝到一个vector中。
如果你不确定应该使用哪种容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下标操作,避免随机访问。这样,在必要时选择使用vector或list都很方便。
一般来说,每个容器都定义在一个头文件中,文件名与类型名相同。即,deque定义在头文件deque中,list定义在头文件list中,以此类推。容器均定义为模板类。
顺序容器几乎可以保存任意类型的元素。特别是,我们可以定义一个容器,其元素的类型是另一个容器。这种容器的定义与任何其他容器类型完全一样:在尖括号中指定元素类型(此种情况下,是另一种容器类型)。
除了顺序容器外,标准库还定义了三个顺序容器适配器:stack、queue和priority_queue。适配器(adaptor)是标准库中的一个通用概念。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。一个容器适配器接受一种已有的容器类型,使其行为看起来像一种不同的类型。下面是从其他文章中copy的std::list测试代码,详细内容介绍可以参考对应的reference:
#include "list.hpp"
#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <cmath>//
// reference: http://www.cplusplus.com/reference/list/list/
// compare only integral part:
static bool mycomparison(double first, double second)
{return (int(first)<int(second));
}// comparison, not case sensitive.
static bool compare_nocase(const std::string& first, const std::string& second)
{unsigned int i = 0;while ((i<first.length()) && (i<second.length())) {if (tolower(first[i])<tolower(second[i])) return true;else if (tolower(first[i])>tolower(second[i])) return false;++i;}return (first.length() < second.length());
}// a predicate implemented as a function:
static bool single_digit(const int& value) { return (value<10); }// a predicate implemented as a class:
struct is_odd {bool operator() (const int& value) { return (value % 2) == 1; }
};// a binary predicate implemented as a function:
static bool same_integral_part(double first, double second)
{return (int(first) == int(second));
}// a binary predicate implemented as a class:
struct is_near {bool operator() (double first, double second){return (fabs(first - second)<5.0);}
};int test_list_1()
{
{ // list::list: Constructs a list container object, initializing its contents depending on the constructor version usedstd::list<int> first; // empty list of intsstd::list<int> second(4, 100); // four ints with value 100std::list<int> third(second.begin(), second.end()); // iterating through secondstd::list<int> fourth(third); // a copy of third// the iterator constructor can also be used to construct from arrays:int myints[] = { 16, 2, 77, 29 };std::list<int> fifth(myints, myints + sizeof(myints) / sizeof(int));std::cout << "The contents of fifth are: ";for (std::list<int>::iterator it = fifth.begin(); it != fifth.end(); it++)std::cout << *it << ' ';std::cout << '\n';
}{ // list::assign: Assigns new contents to the list container, replacing its current contents, and modifying its size accordingly// list::size: Returns the number of elements in the list container.std::list<int> first;std::list<int> second;first.assign(7, 100); // 7 ints with value 100second.assign(first.begin(), first.end()); // a copy of firstint myints[] = { 1776, 7, 4 };first.assign(myints, myints + 3); // assigning from arraystd::cout << "Size of first: " << int(first.size()) << '\n';std::cout << "Size of second: " << int(second.size()) << '\n';
}{ // list::back: Returns a reference to the last element in the list container// list::front: Returns a reference to the first element in the list container.std::list<int> mylist;mylist.push_back(10);while (mylist.back() != 0) {mylist.push_back(mylist.back() - 1);}std::cout << "mylist contains:";for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';mylist.push_back(77);mylist.push_back(22);mylist.front() -= mylist.back();std::cout << "mylist.front() is now " << mylist.front() << '\n';}{ // list::begin: Returns an iterator pointing to the first element in the list container// list::cbegin: C++11, Returns a const_iterator pointing to the first element in the container// list::crbegin: C++11, Returns a const_reverse_iterator pointing to the last element in the container (i.e., its reverse beginning)// list::rbegin: Returns a reverse iterator pointing to the last element in the container (i.e., its reverse beginning).// list::end: Returns an iterator referring to the past-the-end element in the list container// list::cend: C++11, Returns a const_iterator pointing to the past-the-end element in the container// list::crend: C++11, Returns a const_reverse_iterator pointing to the theoretical element// preceding the first element in the container (which is considered its reverse end)// list::rend: Returns a reverse iterator pointing to the theoretical element preceding the first element// in the list container (which is considered its reverse end).int myints[] = { 75, 23, 65, 42, 13 };std::list<int> mylist(myints, myints + 5);std::cout << "mylist contains:";for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';for (auto it = mylist.cbegin(); it != mylist.cend(); ++it)std::cout << ' ' << *it;std::cout << '\n';for (auto rit = mylist.crbegin(); rit != mylist.crend(); ++rit)std::cout << ' ' << *rit;std::cout << '\n';std::cout << "mylist backwards:";for (std::list<int>::reverse_iterator rit = mylist.rbegin(); rit != mylist.rend(); ++rit)std::cout << ' ' << *rit;std::cout << '\n';
}{ // list::clear: Removes all elements from the list container (which are destroyed),// and leaving the container with a size of 0std::list<int> mylist;std::list<int>::iterator it;mylist.push_back(100);mylist.push_back(200);mylist.push_back(300);std::cout << "mylist contains:";for (it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';mylist.clear();mylist.push_back(1101);mylist.push_back(2202);std::cout << "mylist contains:";for (it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::emplace: C++11, The container is extended by inserting a new element at position.// This new element is constructed in place using args as the arguments for its construction.// list::emplace_back: C++11, Inserts a new element at the end of the list, right after its current last element.// This new element is constructed in place using args as the arguments for its construction.// list::emplace_front: Inserts a new element at the beginning of the list, right before its current first element.// This new element is constructed in place using args as the arguments for its construction.std::list< std::pair<int, char> > mylist;mylist.emplace(mylist.begin(), 100, 'x');mylist.emplace(mylist.begin(), 200, 'y');std::cout << "mylist contains:";for (auto& x : mylist)std::cout << " (" << x.first << "," << x.second << ")";std::cout << '\n';mylist.emplace_back(10, 'a');mylist.emplace_back(20, 'b');mylist.emplace_back(30, 'c');std::cout << "mylist contains:";for (auto& x : mylist)std::cout << " (" << x.first << "," << x.second << ")";std::cout << std::endl;mylist.emplace_front(10, 'a');mylist.emplace_front(20, 'b');mylist.emplace_front(30, 'c');std::cout << "mylist contains:";for (auto& x : mylist)std::cout << " (" << x.first << "," << x.second << ")";std::cout << std::endl;
}{ // list::empty: Returns whether the list container is empty (i.e. whether its size is 0).std::list<int> mylist;int sum(0);for (int i = 1; i <= 10; ++i) mylist.push_back(i);while (!mylist.empty()) {sum += mylist.front();mylist.pop_front();}std::cout << "total: " << sum << '\n';
}{ // list::erase: Removes from the list container either a single element (position) or a range of elements ([first,last)).std::list<int> mylist;std::list<int>::iterator it1, it2;// set some values:for (int i = 1; i<10; ++i) mylist.push_back(i * 10);// 10 20 30 40 50 60 70 80 90it1 = it2 = mylist.begin(); // ^^std::advance(it2, 6); // ^ ^++it1; // ^ ^it1 = mylist.erase(it1); // 10 30 40 50 60 70 80 90// ^ ^it2 = mylist.erase(it2); // 10 30 40 50 60 80 90// ^ ^++it1; // ^ ^--it2; // ^ ^mylist.erase(it1, it2); // 10 30 60 80 90// ^std::cout << "mylist contains:";for (it1 = mylist.begin(); it1 != mylist.end(); ++it1)std::cout << ' ' << *it1;std::cout << '\n';
}{ // list::get_allocator: Returns a copy of the allocator object associated with the list containerstd::list<int> mylist;int * p;// allocate an array of 5 elements using mylist's allocator:p = mylist.get_allocator().allocate(5);// assign some values to arrayfor (int i = 0; i<5; ++i) p[i] = i;std::cout << "The allocated array contains:";for (int i = 0; i<5; ++i) std::cout << ' ' << p[i];std::cout << '\n';mylist.get_allocator().deallocate(p, 5);
}{ // list::insert: The container is extended by inserting new elements before the element at the specified positionstd::list<int> mylist;std::list<int>::iterator it;// set some initial values:for (int i = 1; i <= 5; ++i) mylist.push_back(i); // 1 2 3 4 5it = mylist.begin();++it; // it points now to number 2 ^mylist.insert(it, 10); // 1 10 2 3 4 5// "it" still points to number 2 ^mylist.insert(it, 2, 20); // 1 10 20 20 2 3 4 5--it; // it points now to the second 20 ^std::vector<int> myvector(2, 30);mylist.insert(it, myvector.begin(), myvector.end());// 1 10 20 30 30 20 2 3 4 5// ^std::cout << "mylist contains:";for (it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::max_size: Returns the maximum number of elements that the list container can hold.// list::resize: Resizes the container so that it contains n elements// list::size_type: A type that counts the number of elements in a list.unsigned int i;std::list<int> mylist;i = 111111;if (i<mylist.max_size()) mylist.resize(i);else std::cout << "That size exceeds the limit.\n";std::list <int>::size_type ii;ii = mylist.max_size();std::cout << "Maximum possible length of the list is " << ii << "." << std::endl;
}{ // list::merge: Merges x into the list by transferring all of its elements at their respective ordered positions// into the container (both containers shall already be ordered).std::list<double> first, second;first.push_back(3.1);first.push_back(2.2);first.push_back(2.9);second.push_back(3.7);second.push_back(7.1);second.push_back(1.4);first.sort();second.sort();first.merge(second);// (second is now empty)second.push_back(2.1);first.merge(second, mycomparison);std::cout << "first contains:";for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::sort: Sorts the elements in the list, altering their position within the containerstd::list<std::string> mylist;std::list<std::string>::iterator it;mylist.push_back("one");mylist.push_back("two");mylist.push_back("Three");mylist.sort();std::cout << "mylist contains:";for (it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';mylist.sort(compare_nocase);std::cout << "mylist contains:";for (it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::operator=: Assigns new contents to the container, replacing its current contents, and modifying its size accordingly.std::list<int> first(3); // list of 3 zero-initialized intsstd::list<int> second(5); // list of 5 zero-initialized intssecond = first;first = std::list<int>();std::cout << "Size of first: " << int(first.size()) << '\n';std::cout << "Size of second: " << int(second.size()) << '\n';
}{ // list::push_back: Adds a new element at the end of the list container, after its current last element.// list::push_front: Inserts a new element at the beginning of the list, right before its current first element.// list::pop_back: Removes the last element in the list container, effectively reducing the container size by one.// list::pop_front: Removes the first element in the list container, effectively reducing its size by onstd::list<int> mylist;int sum(0);mylist.push_back(100);mylist.push_back(200);mylist.push_back(300);while (!mylist.empty()) {sum += mylist.back();mylist.pop_back();}std::cout << "The elements of mylist summed " << sum << '\n';mylist.push_back(100);mylist.push_back(200);mylist.push_back(300);mylist.push_front(200);mylist.push_front(300);std::cout << "Popping out the elements in mylist:";while (!mylist.empty()) {std::cout << ' ' << mylist.front();mylist.pop_front();}std::cout << "\nFinal size of mylist is " << mylist.size() << '\n';
}{ // list::remove: Removes from the container all the elements that compare equal to val.// This calls the destructor of these objects and reduces the container size by the number of elements removed.// list::remove_if: Removes from the container all the elements for which Predicate pred returns true.// This calls the destructor of these objects and reduces the container size by the number of elements removed.int myints[] = { 89, 15, 36, 7, 17, 20, 39, 4, 1 };std::list<int> mylist(myints, myints + 9);mylist.remove(89);std::cout << "mylist contains:";for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';mylist.remove_if(single_digit); // 15 36 17 20 39mylist.remove_if(is_odd()); // 36 20std::cout << "mylist contains:";for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::reverse: reverses the order of the elements in the list container.std::list<int> mylist;for (int i = 1; i<10; ++i) mylist.push_back(i);mylist.reverse();std::cout << "mylist contains:";for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::splice: Transfers elements from x into the container, inserting them at positionstd::list<int> mylist1, mylist2;std::list<int>::iterator it;// set some initial values:for (int i = 1; i <= 4; ++i)mylist1.push_back(i); // mylist1: 1 2 3 4for (int i = 1; i <= 3; ++i)mylist2.push_back(i * 10); // mylist2: 10 20 30it = mylist1.begin();++it; // points to 2mylist1.splice(it, mylist2); // mylist1: 1 10 20 30 2 3 4// mylist2 (empty)// "it" still points to 2 (the 5th element)mylist2.splice(mylist2.begin(), mylist1, it);// mylist1: 1 10 20 30 3 4// mylist2: 2// "it" is now invalid.it = mylist1.begin();std::advance(it, 3); // "it" points now to 30mylist1.splice(mylist1.begin(), mylist1, it, mylist1.end());// mylist1: 30 3 4 1 10 20std::cout << "mylist1 contains:";for (it = mylist1.begin(); it != mylist1.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';std::cout << "mylist2 contains:";for (it = mylist2.begin(); it != mylist2.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::swap: Exchanges the content of the container by the content of x,// which is another list of the same type. Sizes may differ.std::list<int> first(3, 100); // three ints with a value of 100std::list<int> second(5, 200); // five ints with a value of 200first.swap(second);std::swap(first, second);std::cout << "first contains:";for (std::list<int>::iterator it = first.begin(); it != first.end(); it++)std::cout << ' ' << *it;std::cout << '\n';std::cout << "second contains:";for (std::list<int>::iterator it = second.begin(); it != second.end(); it++)std::cout << ' ' << *it;std::cout << '\n';
}{ // list::unique: Remove duplicate valuesdouble mydoubles[] = { 12.15, 2.72, 73.0, 12.77, 3.14,12.77, 73.35, 72.25, 15.3, 72.25 };std::list<double> mylist(mydoubles, mydoubles + 10);mylist.sort(); // 2.72, 3.14, 12.15, 12.77, 12.77,// 15.3, 72.25, 72.25, 73.0, 73.35mylist.unique(); // 2.72, 3.14, 12.15, 12.77// 15.3, 72.25, 73.0, 73.35mylist.unique(same_integral_part); // 2.72, 3.14, 12.15// 15.3, 72.25, 73.0mylist.unique(is_near()); // 2.72, 12.15, 72.25std::cout << "mylist contains:";for (std::list<double>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';
}{ // Performs the appropriate comparison operation between the list containers lhs and rhsstd::list<int> a = { 10, 20, 30 };std::list<int> b = { 10, 20, 30 };std::list<int> c = { 30, 20, 10 };if (a == b) std::cout << "a and b are equal\n";if (b != c) std::cout << "b and c are not equal\n";if (b<c) std::cout << "b is less than c\n";if (c>b) std::cout << "c is greater than b\n";if (a <= b) std::cout << "a is less than or equal to b\n";if (a >= b) std::cout << "a is greater than or equal to b\n";
}return 0;
}//
// reference: https://msdn.microsoft.com/en-us/library/802d66bt.aspx
int test_list_2()
{using namespace std;// Create an empty list c0 list <int> c0;// Create a list c1 with 3 elements of default value 0 list <int> c1(3);// Create a list c2 with 5 elements of value 2 list <int> c2(5, 2);// Create a list c3 with 3 elements of value 1 and with the // allocator of list c2 list <int> c3(3, 1, c2.get_allocator());// Create a copy, list c4, of list c2 list <int> c4(c2);// Create a list c5 by copying the range c4[ first, last) list <int>::iterator c4_Iter = c4.begin();c4_Iter++;c4_Iter++;list <int> c5(c4.begin(), c4_Iter);// Create a list c6 by copying the range c4[ first, last) and with // the allocator of list c2 c4_Iter = c4.begin();c4_Iter++;c4_Iter++;c4_Iter++;list <int> c6(c4.begin(), c4_Iter, c2.get_allocator());cout << "c1 =";for (auto c : c1)cout << " " << c;cout << endl;cout << "c2 =";for (auto c : c2)cout << " " << c;cout << endl;cout << "c3 =";for (auto c : c3)cout << " " << c;cout << endl;cout << "c4 =";for (auto c : c4)cout << " " << c;cout << endl;cout << "c5 =";for (auto c : c5)cout << " " << c;cout << endl;cout << "c6 =";for (auto c : c6)cout << " " << c;cout << endl;// Move list c6 to list c7 list <int> c7(move(c6));cout << "c7 =";for (auto c : c7)cout << " " << c;cout << endl;// Construct with initializer_list list<int> c8({ 1, 2, 3, 4 });cout << "c8 =";for (auto c : c8)cout << " " << c;cout << endl;return 0;
}
GitHub: https://github.com/fengbingchun/Messy_Test 相关文章:

React组件设计之边界划分原则
简述 结合SOLID中的单一职责原则来进行组件的设计 Do one thing and do it well javaScript作为一个弱类型并在函数式和面对对象的领域里疯狂试探语言。SOLID原则可能与其他语言例如(java)的表现可能是不同的。不过作为软件开发领域通用的原则࿰…

阿里AI labs发布两大天猫精灵新品,将与平头哥共同定制智能语音芯片
作者 | 夕颜出品 | AI科技大本营(ID:rgznai100)2019 年,去年刮起的一阵智能音箱热浪似乎稍微冷却下来,新产品不再像雨后春笋一样层出不穷,挺过市场洗礼的产品更是凤毛麟角,这些产品的性能、技术支持和体验基…

js 中文匹配正则
为什么80%的码农都做不了架构师?>>> /^[\u4e00-\u9fa5]{2,4}$/gi.test() 匹配中文正则 转载于:https://my.oschina.net/fedde/blog/211852
Caffe中对cifar10执行train操作
参考Caffe source中examples/cifar10目录下内容。cifar10是一个用于普通物体识别的数据集,cifar10被分为10类,分别为airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck,关于cifar10的详细介绍可以参考: http://blog.csd…

解决掉这些痛点和难点,让知识图谱不再是“噱头”
(图片付费下载自视觉中国)作者| 夕颜出品| AI科技大本营(ID:rgznai100)2012 年,谷歌正式提出知识图谱的概念,当时,研究人员的主要目的是用来优化搜索引擎技术。今年初,谷歌前员工&am…

mongodb使用常用语法,持续更新
设置快捷命令D:\mongodb4.0.8\bin>mongod --config "D:\mongodb4.0.8\mongo.conf" --auth --install --serviceName "MongoDB"mongodb配置文件#数据库路径dbpathD:\mongodb4.0.8\data\db#日志输出文件路径logpathD:\mongodb4.0.8\data\log\MongoDB.log#…
Android之NDK开发的简单实例
NDK全称为Native Development Kit,是本地开发工具集。在Android开发中,有时为了能更好的重用以前的C/C的代码,需要将这些代码编译成相应的so,然后通地JNI以供上层JAVA调用。当然,也有的是为了更高的保护性和安全性。下…

阿里披露AI完整布局,飞天AI平台首次亮相
作者 | 夕颜编辑 | 唐小引出品 | AI 科技大本营(ID:rgznai100)9 月 26 日上午,在云栖大会阿里云飞天智能主论坛上,年轻的阿里巴巴副总裁、阿里云智能计算平台事业部总经理、高级研究员贾扬清与其在 Facebook 的老同事—— Faceboo…
使用Caffe基于cifar10进行物体识别
在http://blog.csdn.net/fengbingchun/article/details/72953284中对cifar10进行train,这里通过train得到的model,对图像进行识别。cifar10数据集共包括10类,按照0到9的顺序依次为airplane(飞机)、automobile(轿车)、bird(鸟)、cat(猫)、deer…

SoJpt Boot 2.3-3.8 发布,Spring Boot 使用 Jfinal 特性极速开发
SoJpt Boot 2.3-3.8 发布了。SoJpt Boot 基于 JFinal 与 Spring Boot制作, 实现了 Spring Boot 与 Jfinal 的混合双打,使 Spring Boot 下的开发者能够体验 Jfinal 的极速开发特性。新版更新内容如下: SoJpt-Boot-2.3-3.8 changelog 1、加入事务注解,Tx(value"c…

PL/SQL程序设计 第七章 包的创建和应用
7.1 引言包是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合,它具有面向对象程序设计语言的特点,是对这些PL/SQL 程序设计元素的封装。包类似于C和JAVA语言中的类,其中变量相当于类中的成员变量,过程和函数相当…

C++11中头文件chrono的使用
在C11中,<chrono>是标准模板库中与时间有关的头文件。该头文件中所有函数与类模板均定义在std::chrono命名空间中。 std::chrono是在C11中引入的,是一个模板库,用来处理时间和日期的Time library。要使用chrono库,需要incl…

为什么平头哥做芯片如此迅猛?
作者 | 胡巍巍 发自杭州云栖大会责编 | 唐小引来源 | CSDN(ID:CSDNnews)2018年10月31日,阿里旗下的平头哥半导体有限公司成立。如今,平头哥成立不到一年,就已成绩斐然。2019年9月25日,阿里巴巴旗…

Vue 组件库 heyui@1.18.0 发布,新增地址选择、图片预览组件
开发四年只会写业务代码,分布式高并发都不会还做程序员? 新增 CategoryPicker 新增组件 CategoryPicker,地址级联组件的最佳方案。 <CategoryPicker :option"option" v-model"value"/> 相关文档 ImagePreview 新…

HTML5 Dashboard – 那些让你激动的 Web 技术
HTML5 Dashboard 是一个 Mozilla 推出的项目,里面展示了最前沿的 HTML5,CSS3,JavaScript 技术。每一项技术都有简洁,在线演示以及详细的文档链接。这些技术将成为未来一段时间 Web 开发的顶尖技术,如果不想落伍的话就赶…

计算机解决问题没有奇技淫巧,但动态规划还是有点套路
作者 | labuladong来源 | labuladong(ID:labuladong) 【导读】动态规划算法似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高…

idea下,Jetty采用main方法启动web项目
为什么80%的码农都做不了架构师?>>> 对于maven多模块的spring web项目,本地开发时,启动的方式一般有如下几种: 使用容器(tomcat/jetty/resin等),该方式需要ide支持,而社…
概率论中均值、方差、标准差介绍及C++/OpenCV/Eigen的三种实现
概率论是用于表示不确定性声明(statement)的数学框架。它不仅提供了量化不确定性的方法,也提供了用于导出新的不确定性声明的公理。在人工智能领域,概率论主要有两种用途。首先,概率法则告诉我们AI系统如何推理,据此我们设计一些算…

[转]CentOS 5.5下FTP安装及配置
一、FTP的安装 1、检测是否安装了FTP : [rootlocalhost ~]# rpm -q vsftpd vsftpd-2.0.5-16.el5_5.1 否则显示:[rootlocalhost ~]# package vsftpd is not installed 查看ftp运行状态 service vsftpd status 2、如果没安装FTP,运行yum install vsftpd命令进行安装 如…

C++11中头文件thread的使用
C11中加入了<thread>头文件,此头文件主要声明了std::thread线程类。C11的标准类std::thread对线程进行了封装。std::thread代表了一个线程对象。应用C11中的std::thread便于多线程程序的移值。 <thread>是C标准程序库中的一个头文件,定义了…

python3 urllib 类
urllib模块中的方法 1.urllib.urlopen(url[,data[,proxies]]) 打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作。本例试着打开google >>> import urllib >>> f urllib.urlopen(http://www.google.com.hk/) >&…
阿里飞天大数据飞天AI平台“双生”系统正式发布,9大全新数据产品集中亮相
作者 | 夕颜 责编 | 唐小引 出品 | AI科技大本营(ID:rgznai100) 如今,大数据和 AI 已经成为两个分不开的词汇,没有大数据,AI 就失去了根基;没有 AI,数据不会呈现爆发式的增长。如何将 AI 与大…

关于JavaScript的闭包(closure)
(转载自阮一峰博客) 闭包(closure)是Javascript语言的一个难点,也是它的特色,更是函数式编程的重要思想之一,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初…

Vagrant控制管理器——“Hobo”
Hobo是控制Vagrant盒子和在Mac上编辑Vagrantfiles的最佳和最简单的方法。您可以快速启动,停止和重新加载您的Vagrant机器。您可以从头开始轻松创建新的Vagrantfile。点击进入,尽享Hobo for Mac全部功能! Hobo做什么? 启动…

微众银行AI团队开源联邦学习框架,并发布《联邦学习白皮书1.0》
(图片由AI科技大本营付费下载自视觉中国)编辑 | Jane来源 | 《联邦学习白皮书1.0》出品 | AI科技大本营(ID:rgznai100)【导语】2019年,联邦学习成为业界技术研究与应用的焦点。近日,微众银行 AI 项目组编制…

C++11中头文件atomic的使用
原子库为细粒度的原子操作提供组件,允许无锁并发编程。涉及同一对象的每个原子操作,相对于任何其他原子操作是不可分的。原子对象不具有数据竞争(data race)。原子类型对象的主要特点就是从不同线程访问不会导致数据竞争。因此从不同线程访问某个原子对象…

Oracle回收站
回收站是删除对象使用的存储空间。可以使用实例参数recyclebin禁用回收站,默认是on,可以为某个会话或系统设置为off或on。所有模式都有一个回收站。 当表空间不足时可以自动重用回收站对象占用的表空间(此后不可能恢复对象)&#…
协方差矩阵介绍及C++/OpenCV/Eigen的三种实现
函数f(x)关于某分布P(x)的期望(expectation)或者期望值(expected value)是指,当x由P产生,f作用于x时,f(x)的平均值。对于离散型随机变量,这可以通过求和得到:对于连续型随机变量可以通过求积分得到:当概率分…

10分钟搭建你的第一个图像识别模型 | 附完整代码
(图片由AI科技大本营付费下载自视觉中国)作者 | Pulkit Sharma译者 | 王威力来源 | 数据派THU(ID:DatapiTHU)【导读】本文介绍了图像识别的深度学习模型的建立过程,通过陈述实际比赛的问题、介绍模型框架和…

Rancher 2.2.2 发布,优化 Kubernetes 集群运维
开发四年只会写业务代码,分布式高并发都不会还做程序员? >>> Rancher 2.2.2 发布了。Rancher 是一个开源的企业级 Kubernetes 平台,可以管理所有云上、所有发行版、所有 Kubernetes集群,解决了生产环境中企业用户可能面…