vector是一个在c++编程中很常见的一个类型,我们更喜欢称之为容器。
std::vector<int> v;
那么应该如何将数组的内容复制给容器呢?可以一个个去添加(v.push_back()),不过那样是非常的慢.这里可以直接使用容器的构造函数。
int arrays[] = {1,2,3,4,5};
std::vector v(arrays, arrays+5);
int main() {
std::vector<int> v = {3, 1, 4};
auto vi = std::end(v); // find an element after 4
std::cout << std::showpos << *vi << "\n"; // showpos print "+" or "-"
sort(v.begin(), v.end());
std::vector<int>::iterator i; // 使用迭代器
for (i = v.begin(); i != v.end(); i++){
std::cout << *i << " "; // 输出1 3 4
}
std::cout << std::endl;
int a[] = {-5, 10, 16};
auto ai = std::begin(a);
std::cout << *ai << '\n';
}
output:
+0
+1 +3 +4
-5
std::vector<std::vector<int> >array(3); // 二维数组包含三个向量
for (int i = 0; i < 3; i++){
array[i].resize(3); // 设置数组的大小 3*3
}
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
array[i][j] = i * j; // 使用二维数组
}
}
// 输出
for(int i = 0 ; i < 3; i++){
for (int j = 0; j < 3; j++){
cout << array[i][j] << " ";
}
cout << endl;
}
https://blog.csdn.net/sinat_41852207/article/details/86668954
构造函数 vector<vector
// 1. 示例, 一行一行赋值
int a[] = { 1, 2, 3, 4 }; // 把数组的元素放进vector中
vector<int> ivec(a, a + 4);//数组初始化vector,见最下面(也可以不用数组初始化,直接{}初始化vector)
vector<vector<int> > m; // 声明一个二维数组
m.push_back(ivec); // 把ivec(a数组的内容整体放入m,按行)
ivec[0] = 5; ivec[1] = 6; ivec[2] = 7; ivec[3] = 8;
m.push_back(ivec);
ivec[0] = 9; ivec[1] = 10; ivec[2] = 11; ivec[3] = 12;
m.push_back(ivec);
ivec[0] = 13; ivec[1] = 14; ivec[2] = 15; ivec[3] = 16;
m.push_back(ivec);
// 2. 具体赋值某一个值,以某行某列的形式,也就是所谓的直接初始化
vector<vector<char>> board = {
{'X','.','.','X'},
{'.','.','.','X'},
{'.','.','.','X'}
}; // 这样的
我有一个代码,遇到了这样的逻辑,一开始不明白:
class Solution {
public:
vector<vector<int>> result;
vector<vector<int>> levelOrder(TreeNode* root) {
levelOrderHelper(root,0);
return result;
}
void levelOrderHelper (TreeNode* root, int level) {
...
if(level == result.size()) result.push_back(vector<int>()); // 主要是这两行
result[level].push_back({root->val}); // 不太理解
...
}
};
这个方法是可以返回一个有序的容器类的第一个小于其中元素的索引。其效率为log2(N) + 1.看来真滴该研究下合格stl。高效。
int myints[] = {10, 20, 30, 30, 20, 10, 10 ,20};
std::vector<int> v(myints, myints + 8);
std::sort(v.begin(), v.end()); // 10 10 10 20 20 20
std::vector<int>::iterator low,up; // HERE,^_^
low = std::lower_bound(v.begin(), v.end(), 20);
up = std::upper_bound(v.begin(), v.end(), 20);
cout << "low_bound at position " << (low - v.begin()) << endl;;
cout << "up_bound at position " << (up - v.begin()) << endl;
结果:
low_bound at position 3 up_bound at position 6
通过上面的注释也许你已经注意到了,注意这个方法的类型,如果想得到整型的索引,还需要减去v.begin()
才可以得到。
要求:
Sample Input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Sample Output
5
9
程序如下:
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int row,query,col,temp;
int **v = NULL;
cin >> row >> query;
v = new int*[row];
for(int i = 0; i < row ; i++){
cin >> col;
v[i] = new int[col];
for (int j = 0; j < col; j++) {
cin >> temp;
v[i][j] = temp;
}
}
for (int i = 0; i < query; i++) {
int t1, t2;
cin >> t1 >> t2;
cout << v[t1][t2] << endl;
}
for(int i = 0; i < row; i++){
delete []v[i];
v[i] = NULL;
}
delete []v;
v = NULL;
return 0;
}
这里set和vector还有具有一定区别的,至少从内置的方法来说,他们的特点差别还是挺大的。那有没有协调array vector和set的方法?我想一定会有的。
上面的这句话后来在后来回顾时发现错的太离谱。set本身具有hashtable的属性,这才是set真正的意义所在。
set<int> s;
s.size()
s.insert(x)
s.erase(x)
这一点也是vector没有的吧?
set<int>::iterator itr = s.find(x);
如果没有找到,则有itr == s.end()
, s.end()并不指向最后一个元素,而只是标志结束。
它的操作和map还是很相近的。
不要求具有特殊的顺序,无序的都可以。方法有count,insert等。
#include <string>
#include <unordered_set>
using namespace std;
int main(){
std::unordered_set<std::string> myset = {"hat", "umberlla", "suit"};
for (auto& x: {"hat", "sunglass", "suit"}){
if(myset.count(x) > 0)
std::cout << "myset has " << x << std::endl;
else
std::cout << "myset does not have " << x << std::endl;
}
}
输出:
myset has hat
myset does not have sunglass
myset has suit
其实,如果是做算法题目的话,c++是一定需要掌握的语言(对于纯c来讲,也许真正的c大师完全可以纯手撸出来)。现在,自己简单记录下c++中基本的数据结构的用法,今天重点回忆map。
map的基本概念不用解释,就是简单的”key”,”value”嘛,主要看操作。
map<int, int> m; // 声明存储两个整型的key value
map<string, int> m;// decliam a map with string key typo and value int typo
我认为每一个数据结构都有自己的遍历方式,这是必须掌握的一种机制。使用c++的遍历呢,我们不能忘记iterator。
map<string, int> m;
m["yubo"] = 1;
m["hechun"] = 2;
map<string, int>::iterator iter = m.begin();
while(iter != m.end()){
cout<< iter->first << ":" << iter->second <<endl;
iter++;
}
/* 还可以使用for
map<string, int>::iterator iter = m.begin();
for(; iter != m.end(); iter++)
cout<< iter->first<< ":"<<iter->second<<endl;
*/
使用for需要注意的地方就是,判断条件不能使用”<”(在迭代中)
哈哈,非常有意思!起初我还以为map是类似栈式的管理,看来真实贻笑大方了。目前来说,map这个数据结构可以按照key的值自动排序。当然,这个排序你可以使用,也可以不使用;既可以这样排序,也可以那样排序!有意思啊
另外注意的就是,end()指针没有指向元素,如果,特定需要end()的元素,需要提前减1.
map<string, int> m;
m["yubo"] = 1;
m["hechun"] = 2;
map<string, int>::iterator _start, _end;
_start = m.begin();
_end = m.end();
_end--;
cout << _start->first<<endl;
cout << _end->first << endl;
结果先输出”hechun”,再输出”yubo”
以上面代码为例的话,就是删除遍历指针
m.erase(_start)
map<string,int>::iterator itr=m.find(val); //Gives the iterator to the element val if it is found otherwise returns m.end() .
Ex: map<string,int>::iterator itr=m.find("Maps"); //If Maps is not present as the key value then itr==m.end()."")
还是使用遍历指针:
To get the value stored of the key “MAPS” we can do m[“MAPS”] or we can get the iterator using the find function and then by itr->second we can access the value.
使用 `std::pair<string, int>(),还可以参观这个 article
首先输入一个数字,代表后面有几个输入行:
7
1 Jesse 20
1 Jess 12
1 Jess 18
3 Jess
3 Jesse
2 Jess
3 Jess
其中,’1’代表插入姓名和成绩,当然有多个相同,需要自己更新的。’2’代表删除该学生的信息,’3’代表查询该学生的成绩。 Solution:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
map<std::string, int> m;
int n, type;
cin >> n ; // nums of query
for(int i = 0; i < n;i++){
string name;
int marks;
cin >> type; // the first type on per line
if (type == 1){
cin >> name >> marks; // how to iter and update value
map<string,int>::iterator iter = m.find(name);
if(iter == m.end())
m.insert(std::pair<string, int>(name, marks));
// maybe use
else
iter->second += marks; // update value
}
else if (type == 2){
cin >> name;
m.erase(name);
} else {
cin >> name;
cout << m[name] << endl; //
}
}
return 0;
}
其中,插入元素那里值得注意,上面的方法使用m.insert(std::pair<string, int>(name, marks))
,
还可以使用make_pair()
的方法, 注意,这里没有 <>
.
前面介绍的map是一个唯一键的有序序列,而在unordered_map中键可以以任何顺序存储,所以是无序的。Map是作为平衡的树结构实现的,这就是为什么可以维护元素之间的顺序(通过特定的树遍历)。map操作的时间复杂度为O(Log n),而对于unordered_map,平均为O(1)。
以下代码如同map的代码一样,没有什么特别的地方。
#include <unordered_map>
#include <iostream>
using namespace std;
int main() {
unordered_map<string, int> umap;
// insert values by using "[]" operator
// 当然 还可以使用make::pair的形式插入进去 umap.insert(make_pair("e", 2.718));
umap["vimer"] = 10;
umap["test"] = 11;
umap["lele"] = 12;
for(const auto &entry : umap){ // 使用引用的方式 省去copy的开销
cout << entry.first <<" " <<entry.second << endl;
}
}
如果value值为其他容易,在插入新值之前,需要先做初始化。如下:
using namespace std;
int main() {
unordered_map<string, vector<int>> keys;
keys["a"] = vector<int>(); // Initialize key with all null vector
keys["a"].push_back(1);
keys["a"].push_back(2);
for (const int &x : keys["a"]){
cout << x << endl;
}
}
或者其他类似的:
drawQueue.insert(std::make_pair(type, std::vector<Object*>()));
// If using C++11, the previous statement can be simplified to:
drawQueue.emplace(type, std::vector<Object*>());
参考这里
下面介绍几个API。
这个方法可以看成测试某一个keys是否存在map容器中, 如下:
#include <iostream>
#include <string>
#include <unordered_map>
int main ()
{
std::unordered_map<std::string,double> mymap = {
{"Burger",2.99},
{"Fries",1.99},
{"Soda",1.50} };
for (auto& x: {"Burger","Pizza","Salad","Soda"}) {
if (mymap.count(x)>0)
std::cout << "mymap has " << x << std::endl;
else
std::cout << "mymap has no " << x << std::endl;
}
return 0;
上面的代码摘自c++.com c++实在是太变态了。
string作为c++的一个标准stl,仅凭这一点就应该比c方便很多了(c大神勿喷)。
使用等号的叫做拷贝初始化,不适用等号的初始化叫做直接初始化。
string s;//默认初始化
string s1("ssss");
cout << s1<<endl;
string s2(s1);
string s3 = s2;
cout<<s3<<endl;
string s4(10, 'c'); // 生成一个10个‘c’的s4
cout<<s4<<endl;
char cs[] = "hello,world";
string s7(cs, 4); // 复制cs的前4个字符给s7
string s1= "hello,world";
string s8(s1,4); // 从s1的pos4开始赋值给s8,其大小不超过s1的size
string s9(s1, 4,3);
string s9(s1, 4,3); //从s1的第四位开始,符给3个字符给s9,超出的未定义
string s = "helloyubo";
string s2 = s.substr(1,5); //数字分别表明起点和终点位置
cout << s2<<endl;
string s3 = s.substr(1);// 从1一直到最后
cout << s3<<endl;
cout << s9<<endl;
如果输入的位置超出了字符的长度,则会抛出一个out_of_range的异常。
先看代码。
string str = "to be question";
string str2 = "the ";
string str3 = "or not to be";
string::iterator it;
str.insert(6, str2); // c++的string从1开始计数
str.insert(6, str3, 3, 4); // 在pos 6的位置上,插入str3从pos 3 开始,往后截取4个字符
str.insert(14, " that is cool", 8); //在14的 pos上插入8个字符
str.insert(6, " or not to be "); // 在pos 6上面,插入后面的字符串
str.insert(6, 3,':'); // 在pos 6的位置上插入3个':'
it = str.insert(str.begin()+5, ',');// 注意上面的str都保持了初始声明的样子
//这里的begin+5,是从0数到4的,返回的*it是当前位置的内容
cout << str << endl; // to be, question
str.insert(str.end(), 3,':');// 在str的末尾处插入3个':'
//to be, question:::
string设计区间操作的一般为左开右闭。下面的代码具有连续性,也就是说,经过一条语句后对另一条语句是有影响的。
std::string str("This is c++");
std::cout << str << '\n';// This is c++
str.erase(5,2);
std::cout << str <<'\n'; //This c++ 擦除在pos 5后面的2位
str.erase(str.begin()+5);
std::cout << str<<'\n';//This c++ 擦除迭代器所处的位置上的内容
str.erase(str.begin()+6, str.end());
std::cout << str << '\n';//This c 擦除迭代器之间的内容
append()的用法
std::string str;
std::string str2 = "hello";
std::string str3 = " world,yubo";
str.append(str2);
std::cout << str << '\n'; //hello
str.append(str3, 7, 4);
std::cout << str << '\n'; //helloyubo
str.append("haha", 4);
std::cout << str << '\n'; //helloyubohaha
str.append("hechun");
std::cout << str << '\n'; //helloyubohahahechun
str.append(10u, '*');
std::cout << str << '\n'; //helloyubohahahechun**********
str.append<int>(5,65); //helloyubohahahechun**********AAAAA
std::cout<< str <<'\n';
直接粘replace()用法的代码
std::string base="this is a test string.";
std::string str2="n example";
std::string str3="sample phrase";
std::string str4="useful.";
// replace signatures used in the same order as described above:
// Using positions: 0123456789*123456789*12345
std::string str=base; // "this is a test string."
//第9个字符以及后面的4个字符被str2代替
str.replace(9,5,str2); // "this is an example string." (1)
//第19个字符串以及后面的5个字符用str的第7个字符以及后面的5个字符代替
str.replace(19,6,str3,7,6); // "this is an example phrase." (2)
//第8个字符以及后面的9个字符用字符串参数代替
str.replace(8,10,"just a"); // "this is just a phrase." (3)
//第8个字符以及后面的5个字符用字符串参数的前7个字符替换
str.replace(8,6,"a shorty",7); // "this is a short phrase." (4)
//第22以及后面的0个字符用3个叹号替换
str.replace(22,1,3,'!'); // "this is a short phrase!!!" (5)
//迭代器的原理同上
// Using iterators: 0123456789*123456789*
str.replace(str.begin(),str.end()-3,str3); // "sample phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace"); // "replace phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7); // "replace is cool!!!" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful." (6)
std::cout << str << '\n';
return 0;
}
代码如下:
#include <iostream>
#include <string>
int main ()
{
std::string str;
std::string base="The quick brown fox jumps over a lazy dog.";
// used in the same order as described above:
//直接把base赋值给str
str.assign(base);
std::cout << str << '\n';
//把base第10个字符以及后面的8个字符赋给str
str.assign(base,10,9);
std::cout << str << '\n'; // "brown fox"
//把参数中的0到6个字符串赋给str
str.assign("pangrams are cool",7);
std::cout << str << '\n'; // "pangram"
//直接使用参数赋值
str.assign("c-string");
std::cout << str << '\n'; // "c-string"
//给str赋值10个'*'字符
str.assign(10,'*');
std::cout << str << '\n'; // "**********"
//赋值是10个'-'
str.assign<int>(10,0x2D);
std::cout << str << '\n'; // "----------"
//指定base迭代器范围的字符串
str.assign(base.begin()+16,base.end()-12);
std::cout << str << '\n'; // "fox jumps over"
return 0;
}
代码:
ios::sync_with_stdio(false);
std::string str("There are two needles in this haystack with needles.");
std::string str2("needle");
//寻找第一次出现的needle,找到返回出现的位置,否则返回结尾
std::size_t found = str.find(str2);
if(found != std::string::npos)
std::cout << "first 'needle' found at " << found << '\n'; // first 'needle' found at 14
// 如果是str2 是neede,则结果为 NULL
found = str.find("needles are small",found + 1, 6);
if(found != std::string::npos)
std::cout << "second 'needle' found at" << found << '\n'; //first 'needle' found at 14
//second 'needle' found at44
// 需要注释掉上面的语句
//还可以查找一个字符
函数查找最后一个出现的的字符串
这里偷懒下,直接使用csdn的代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string s1="123",s2="123";
cout<<s1.compare(s2)<<endl;//0
s1="123",s2="1234";
cout<<s1.compare(s2)<<endl;//-1
s1="1234",s2="123";
cout<<s1.compare(s2)<<endl;//1
std::string str1 ("green apple");
std::string str2 ("red apple");
if (str1.compare(str2) != 0)
std::cout << str1 << " is not " << str2 << '\n';
//str1的第6个字符以及后面的4个字符和参数比较
if (str1.compare(6,5,"apple") == 0)
std::cout << "still, " << str1 << " is an apple\n";
if (str2.compare(str2.size()-5,5,"apple") == 0)
std::cout << "and " << str2 << " is also an apple\n";
//str1的第6个字符以及后面的4个字符和str2的第4个字符以及后面的4个字符比较
if (str1.compare(6,5,str2,4,5) == 0)
std::cout << "therefore, both are apples\n";
return 0;
}
这个方法也很特殊,他可以自己在一串混合字符串中自动摘取整型或者其他你指定的东西。其实,上面已经介绍了 ostringstream这个类,还有一个istringstream的用法。 比如:
stringstream ss("23,4,56");
char ch;
int a, b, c;
ss >> a >> ch >> b >> ch >> c; // a = 23, b = 4, c = 56
下面的题目要求是在一串”24,5,26”的字符串中,将数字提取出来并存放到vector中。
vector<int> parseInts(string str)
{
vector<int> vec;
stringstream ss(str); // Declares a stringstream object to deal
char ch; // -> ','
int temp;
while(ss){ // ss will be terminated by NULL byte
ss >> temp >> ch; // Extract the comma with >> operators
vec.push_back(temp);
}
return vec;
}
上面一定注意stringstream()
实例化的参数就是你要处理的string
strtok
这个函数,当然,在c++中,如果要直接使用string
类型的东西交给
strtok
处理,需要首先转化为char*
。vector<int> parseInts(string str) {
vector<int> nums;
char* s_char = (char *)str.c_str(); // 这个转换将string -> char *,很重要的一个语法。
const char* spilt = ","; // const 好习惯
char* p = strtok(s_char, spilt); // 需要知道这个函数的实现
int a; // "24,25,26"
while(p != NULL){
// char* -> int
sscanf(p, "%d", &a);
nums.push_back(a);
p = strtok(NULL, spilt);
}
s_char = NULL;
return nums;
}
函数原型为 char *strtok(char s[], const char *delim);头文件
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
如果字符串是c++的string类,需要使用上面代码中的
char* s_char = (char *)str.c_str()
转化成为char*才能接着使用。第一个简单的例子:
char str[] = "- This, a sample string.";
char *pch;
printf("Spliting string \"%s\" into token:\n", str);
pch = strtok(str, " ,.-"); // 有四种分隔符
while(pch != NULL){
printf("%s\n", pch);
pch = strtok(NULL, " ,.-"); // 这里面的str参数成为NULL
}
结果如下:
vimer@host:~/test$ g++ -g getline.cpp -o getline
vimer@host:~/test$ ./getline
Spliting string "- This, a sample string." into token:
This
a
sample
string
第二个例子是这样子的:
char str2[] = "";
int in=0;
char *p[20];
char buffer[INFO_MAX_SZ]="Fred male 25,John male 62,Anna female 16";
char *buf = buffer;
while((p[in] = strtok(buf, ",")) != NULL){
in++;
buf = NULL;
}
for (int j = 0; j < in; j++){
cout << " " << p[j] << endl;
}
结果如下:
vimer@host:~/test$ g++ -g getline.cpp -o getline
vimer@host:~/test$ ./getline
Fred male 25
John male 62
Anna female 16
这是一个处理I/O输入输出流的大招,在头文件
char *str = (char *)malloc(sizeof (x));
sprinf(str, "%s %d", char_s, int_x);
str[last] = '\0';
string s = "Hello";
int a = 520;
char* buf = new char[10]; // 2147483647 int的最大值
_itoa(a, buf ,10); // 注意,这里float或者double转化有一些问题
//重点是第三个参数,决定了进制
cout << s + buf << endl;
ostringstream oss;
int a = 4520;
string str = " hello";
oss << str << a; // 现在,str和a的内容已经进入oss对象中
cout << oss.str() << endl; // 可以正常输出了
// 打印 hello 4350
int a = 520;
float b = 5.20;
string str = "Hello";
string res = str + to_string(a);
res.resize(4); // here, we need to be noticed
cout << res << endl;
这一个就是与ostringstream相反的过程,也就是输入。先看一个简单例子:
string str = "hello vimer and linux\tand\nenter";
vector<string> arr;
istringstream ss(str);
string word;
while(ss >> word){
arr.push_back(word);
}
for (size_t i = 0; i < arr.size(); i++)
cout << arr[i] << endl;
// output:
/*
hello
vimer
and
linux
and
enter
*/
注意,被ss实例化的的str可以被默认分割空格、tab、回车换行,也就是可以借用制定字符分割字符串。
这里说的还是比较全面的,尤其九章here
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Other than f(n) = f(n-1) + f(n-2); there are another solution:
nt climbStairs(int n){
int a = 1, b = 1;
while(n--){
a = (b += a) - a;
printf("the n is %d\t, a is %d and b is %d\n", n+1, a, b);
}
return a;
}
If n == 5, Paste my output code above:
the n is 5 , a is 1 and b is 2
the n is 4 , a is 2 and b is 3
the n is 3 , a is 3 and b is 5
the n is 2 , a is 5 and b is 8
the n is 1 , a is 8 and b is 13
There is solution that i dont understand about “w[idx^1]” 这里解释一点就是,根据上面资料的介绍,这种类型的可以归纳为序列(一维)型的。
here “12” -> “L” 或者 (A,B) 共2中解码方式
“226” -> “A, B, F”,“B,Z”, “VF(22, 6)” -> 共3种解码方式。 这也是一种序列性,符合动态规划的三个特定问题:
先来看看有没有共性。如果是s[0] == ““或者s[0] == “x”,一位数的话,肯定是1了,假设dp[0] = 1; 当然,这个dp的大小你要和字符串同大小(为了安全,扩大一个没问题)。
两位数字,s[1,2] == “12”, 由于c的数组下标从0可以,这里注意,i开始从s[1]进入了,到strlen(s)为止。
1 == i, 就是判断s[0] == “0”(为什么),这个题目的难点就在这里,这属于剪枝的方法,s[0] == “0”了,没有以0开头的两位数,所以不符合。当s[i] != 0, d[i] == dp[i - 1], 否则就是dp[i] = 0; dp[i] = (s[i - 1] == ‘0’) : 0 ? dp[i-1]
2 == i: s[i - 2] == ‘2’ && s[i - 1] <= “6” 或者 s[i - 2] == ‘1’,因为这种情况都可以拆成2个组合,dp[i] = dp[i] + dp[i - 2]
然后分别 s = “226”, s = “106”,代入进去观察一下执行顺序。
int numDecodings(char * s){
int len = strlen(s),ret =0;
int *dp = (int *)malloc(sizeof(s) * len + 1);
if (s[0] == '0')
return 0;
dp[0] = 1;
int i;
for(i = 1; i <= len; i++){
dp[i] = (s[i - 1] == '0') ? 0 : dp[i - 1];
}
if( i > 1 && (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6'))){
dp[i] = dp[i] + dp[i - 2];
}
}
ret = dp[i-1];
free(dp);
return ret;
}
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).
How many possible unique paths are there?
看看,这是标准的动态规划的问题呀人! Example 1:
Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right
按照题目给的样例,这里有一个问题,貌似就是起点为(1,1)。 If we initial an 2-D array, it must begin from 0 to n(numbers of elements n - 1 we assume).
Yeap, In the problem, i resolved the issue that firstly was mallocing a 2-D array.I allocate a M x Narray.
int **dp = (char **)malloc(sizeof(int \*) \* m);
Becasue we allocate a 2-D array, which has m row(行).That is said to be allocated row’s elements.
for(i = 0; i < m; i++)
dp[i] = (char *)malloc(sizeof(char) * n);
In the statement, we alloc the each row with n (column 列元素) elements.
for(i = 0; i < n; i++)
dp[0][i] = 1;
for(i = 0; i < m; i++)
dp[i][0] = 1;
int uniquePaths(int m, int n){
if(m == 0 || n == 0)
return 0;
if (m == 1 || n == 1)
return 1;
int **dp = (int **)malloc(sizeof(int *) * m);
int i, j,ret = 0;;
for(i = 0; i < m; i++)
dp[i] = (int *)malloc(sizeof(int) * n);
/* malloc 2-d array */
for(i = 0; i < n; i++)
dp[0][i] = 1;
for(i = 0; i < m; i++)
dp[i][0] = 1;
for(i = 1; i < m; i++)
for(j = 1; j < n;j++){
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
ret = dp[i- 1][j - 1];
free(dp);
return ret;
}
oThe Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,
F(0) = 0, F(1) = 1 F(N) = F(N - 1) + F(N - 2), for N > 1.
参赛指南 赛题 赛题名称 软件定义网络性能验证平台
赛题背景 思博伦通信(SPIRENT)参与了国内外几乎所有的运营商级软件定义网络(SDN)的概念验证、选型测试、网络验收及业务部署等生命周期各个阶段的测试工作,相对于传统TCP/IP网络,SDN的挑战往往来自于集中控制和分布式实施带来的性能问题,如何在SDN网络部署之前完成相关控制器的功能及性能测试、组网规模验证是目前SDN运营方面急待解决的问题。 本题目旨在采用虚拟化技术帮助业界实现灵活的SDN相关评估测试方案,为未来的SDN新技术拓展及部署提供更加便捷的技术验证手段。 赛题要求 采用软件定义网络及虚拟化技术,可使用开源软件和框架设计,通过软件定义的方式,灵活定制生成符合特定要求的虚拟仿真SDN网络,对流经SDN网络的数据流量进行分析识别、分类处理;思博伦可向参赛队伍提供专业的Spirent TestCenter虚拟化测试仪,对数据流量进行指标评测,验证数据流量的分析识别、分类处理是否正确。 在实现基本功能的基础上,还需满足如下具体要求:
EP3思博伦赛项系列讲座之一: SDN/openflow网络架构及其部署-参考案例简介 第一期录屏
EP3思博伦赛项系列讲座之二: 从测试的角度看网络第二期录屏
EP3思博伦赛项系列讲座之三: STCa的配置与安装第三期录屏
EP3思博伦赛项系列讲座之四:网络测试领域“旗舰”工具Spirent TestCenter简介 第四期录屏
仅供参考,不保证信息的准确,有问题请联系 yuzibode#126.com (#=>@)
学习之前一定定一个目标才可以.
使用Packet-In消息的目的是为了将到达OpenFlow交换机的数据包发送至OpenFlow控制器。以下2种情况即可发送Packet-In消息
不存在与流表项一致的项目时(Table-miss),OFPR_NO_MATCH
匹配的流表项中记载的行动为“发送至OpenFlow控制器”时,OFPR_ACTION
发送Packet-In消息时OpenFlow交换机分为两种情况,一种是缓存数据包,一种是不缓存数据包。如果不通过OpenFlow交换机缓存数据包,那么Packet-In消息的buffer_id字段设置为-1,将整个数据包发送至OpenFlow控制器。 如果通过OpenFlow交换机缓存数据包,那么以通过SET_CONFIG消息设置的miss_send_len为最大值的数据包数据将发送至OpenFlow控制器。 miss_send_len的默认值为128。未实施SET_CONFIG消息的交换时,使用该默认值
cket-Out消息是从OpenFlow控制器向OpenFlow交换机发送的消息,是包含数据包发送命令的消息”。 若OpenFlow交换机的缓存中已存在数据包,而OpenFlow控制器发出“发送该数据包”的命令时,该消息指定了表示相应数据包的buffer_id。使用Packet-Out消息还可将OpenFlow控制器创建的数据包发送至OpenFlow交换机。此时,buffer_id置为-1,在Packet-Out消息的最后添加数据包数据。
在2019年的7月份,我还有半年就能够毕业(如果能过顺利毕业的话),为什么说这句话呢?
因为我感觉自己真的难以顺利毕业了,因为这看似无头绪的论文。问题还是出在了自己的身上,自己选了eBPF这个方向。其实呢,有时候自己也会在想,如果没有能够读研会怎样,会不会后悔?
哈哈,我觉得我读研最大的动力在我女朋友身上,尽管她也因为种种原因而后悔读研了,但是,人生不试试谁又能知道合不合适呢?
内核这个方向,是我自己选择的,希望自己努力弥补这三年落下的知识。
论文,尽管定型,尽力去做,去尝试。
如果这两年,尤其是今年给我最大的忠告就是,我,自己要自律,向手机宣战,珍惜时间。
这已经是2019年的29周了,时间已经过去一半多。留给自己的时间真的不多了。 我也知道记录一些这样的流水账,也许效果、意义不大,但是还是希望自己能够鞭策自己,砥砺前行