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

除了淘宝还有哪些购物网站seo新人怎么发外链

除了淘宝还有哪些购物网站,seo新人怎么发外链,松江做公司网站,自己做的主页网站怕被劫持目录 一.string类的成员变量与成员函数 二.string类的接口实现 1.构造函数,析构函数,拷贝构造函数,赋值重载 (1)构造函数 (2)析构函数 (3)拷贝构造函数 &…

目录

一.string类的成员变量与成员函数

二.string类的接口实现

1.构造函数,析构函数,拷贝构造函数,赋值重载

(1)构造函数

(2)析构函数        

(3)拷贝构造函数

(4)赋值重载 

2.迭代器        

3.容量:size,capacity,empty,resize,reserve

(1)size

(2)capacity

(3)empty

(4)reserve

(5)resize

4.访问:operator[]

5.修改:push_back,operator+=,append,clear,swap,c_str

(1)push_back

(2)operator[]

(3)append

(4)operator+=

(5) clear

(6)swap

(7)c_str

6.逻辑运算符

7.查找:find 

8.在固定位置插入数据:insert

9.删除固定位置的数据:erase

10.流插入,流提取运算符重载:<<,>>

(1)流插入<<

(2)流提取>>

三.现代版写法的string类

1.构造函数

2.拷贝构造函数

3.赋值重载

四.代码总览 

string.h

string.cpp

test.cpp


一.string类的成员变量与成员函数

namespace my_string
{class string{friend std::ostream& operator<<(std::ostream& _cout, const my_string::string& s);friend std::istream& operator>>(std::istream& _cin, my_string::string& s);public:typedef char* iterator;typedef const char* const_iterator;string(const char* str = ""):_size(strlen(str)){                                                              _str = new char[_size + 1];_capacity = _size;memcpy(_str, str, _size + 1);}string(const string& s){_str = new char[s._capacity + 1];memcpy(_str, s._str, s._size + 1);_size = s._size;_capacity = s._capacity;}string& operator=(const string& s){char* tmp = new char[s._capacity + 1];memcpy(tmp, s._str, s._size + 1);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}// iteratoriterator begin();iterator end();const_iterator begin() const;const_iterator end() const;// capacitysize_t size() const;size_t capacity() const;bool empty() const;void resize(size_t n, char c = '\0');void reserve(size_t n);// accesschar& operator[](size_t index);const char& operator[](size_t index)const;// relational operatorsbool operator<(const string& s);bool operator<=(const string& s);bool operator>(const string& s);bool operator>=(const string& s);bool operator==(const string& s);bool operator!=(const string& s);// modifyvoid push_back(char c);string& operator+=(char c);void append(const char* str);string& operator+=(const char* str);void clear();void swap(string& s);const char* c_str() const;// 返回c在string中第一次出现的位置size_t find(char c, size_t pos = 0) const;// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0) const;// 在pos位置上插入字符c/字符串str,并返回该字符的位置string& insert(size_t pos, char c);string& insert(size_t pos, const char* str);// 删除pos位置上的元素,并返回该元素的下一个位置string& erase(size_t pos, size_t len);private:char* _str;size_t _size;size_t _capacity;public:static const size_t npos;};
}

二.string类的接口实现

1.构造函数,析构函数,拷贝构造函数,赋值重载

(1)构造函数

string(const char* str = ""):_size(strlen(str))
{                                                              _str = new char[_size + 1];_capacity = _size;memcpy(_str, str, _size + 1);
}

        _size在初始化列表中用给定的字符串的长度初始化,若没有给定字符串,则采用缺省值的空字符串。

        在函数体内初始化_str,new一个size+1大小的连续空间,用来存放给定的字符串的‘\0’,申请完空间后,最后将给定字符串中的数据按字节拷贝给_str。

(2)析构函数        

~string()
{delete[] _str;_str = nullptr;_size = _capacity = 0;
}

(3)拷贝构造函数

string(const string& s)
{_str = new char[s._capacity + 1];memcpy(_str, s._str, s._size + 1);_size = s._size;_capacity = s._capacity;
}

        如果在这里不写拷贝构造,那么编译器则会调用默认的拷贝构造来进行浅拷贝,则会导致同一块空间被析构两次,所以这里需要手动写深拷贝,并将数据按字节转移到新对象中。

(4)赋值重载 

string& operator=(const string& s)
{char* tmp = new char[s._capacity + 1];memcpy(tmp, s._str, s._size + 1);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;
}

        赋值重载与拷贝构造的区别在于需要将被赋值对象所申请的资源释放,并返回被赋值的对象,实现连续赋值。

2.迭代器        

        string类的迭代器以指针为底层逻辑进行实现:

typedef char* iterator;
typedef const char* const_iterator;
string::iterator string::begin()
{return _str;
}string::iterator string::end()
{return _str + _size;
}string::const_iterator string::begin() const
{return _str;
}string::const_iterator string::end() const
{return _str + _size;
}

        有了迭代器之后就可以实现范围for:

3.容量:size,capacity,empty,resize,reserve

(1)size

size_t string::size() const
{return _size;
}

(2)capacity

size_t string::capacity() const
{return _capacity;
}

(3)empty

bool string::empty() const
{return _size == 0;
}

(4)reserve

        reserve所传的参数n一般分为两种情况:

        根据std中的reserve,我们在n<capacity的情况下,对容量不做处理。 

        在n>capacity的情况下,进行异地扩容,并将原数据复制到新空间中,释放旧空间,更新capacity大小:

void string::reserve(size_t n)
{if (n > _capacity){char* tmp = new char[n + 1];memcpy(tmp, _str, _size + 1);delete[] _str;_str = tmp;_capacity = n;}
}

(5)resize

        resize所传的参数n一般分为三种情况:

        当n<size,删除数据,不改变容量。

        当size<n<capacity,插入数据,不改变容量。

        当n>capacity,先进行扩容,再插入数据。

        由于resize如果不传用来插入的数据c,则直接用'\0'进行填充,所以缺省值采用'\0':

void resize(size_t n, char c = '\0')
{if (n < _size){_str[_size] = '\0';}else{if (n > _capacity){reserve(n);}for (int i = _size; i < n; i++){_str[i] = c;}}_size = n;
}

4.访问:operator[]

char& string::operator[](size_t index)
{return _str[index];
}const char& string::operator[](size_t index) const
{return _str[index];
}

5.修改:push_back,operator+=,append,clear,swap,c_str

(1)push_back

void string::push_back(char c)
{if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}_str[_size++] = c;_str[_size] = '\0';
}

(2)operator[]

string& string::operator+=(char c)
{push_back(c);return *this;
}string& string::operator+=(const char* str)
{append(str);return *this;
}

(3)append

void string::append(const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){// 扩容size_t newcapacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;reserve(newcapacity);}memcpy(_str + _size, str, len + 1);_size += len;
}

(4)operator+=

// += 单个字符
string& string::operator+=(char c)
{push_back(c);return *this;
}// += 字符串
string& string::operator+=(const char* str)
{append(str);return *this;
}

(5) clear

void string::clear()
{_str[0] = '\0';_size = 0;
}

(6)swap

void string::swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}

(7)c_str

const char* string::c_str() const
{return _str;
}

6.逻辑运算符

        对于比较运算符,字符的ASCII码相等,则继续比较,不相等,则根据实际情况返回比较结果,若到比较结束,并未返回,则根据字符串的长度来决定返回结果:

        以operator<和operator==为例:

bool string::operator<(const string& s)
{size_t end1 = _size - 1;size_t end2 = s._size - 1;size_t begin1 = 0;size_t begin2 = 0;while (begin1 != end1 && begin2 != end2){if (_str[begin1] < s._str[begin2]){return true;}else if (_str[begin1] > s._str[begin2]){return false;}begin1++;begin2++;}//if (begin1 == end1 && begin2 != end2)//{//	return true;//}//else//{//	return false;//}return begin1 == end1 && begin2 != end2;
}bool string::operator==(const string& s)
{size_t end1 = _size - 1;size_t end2 = s._size - 1;size_t begin1 = 0;size_t begin2 = 0;while (begin1 != end1 && begin2 != end2){if (_str[begin1] != s._str[begin2]){return false;}begin1++;begin2++;}return begin1 == end1 && begin2 == end2;
}

        这里的比较没有使用strcmp的原因是strcmp在遇到'\0'后则不再比较,无法解决字符串中包含'\0'的情况。 

        在实现了任一比较大小和相等后,剩余的比较运算符则可以直接进行复用:

bool string::operator<=(const string& s)
{return *this < s || *this == s;
}bool string::operator>(const string& s)
{return !(*this <= s);
}bool string::operator>=(const string& s)
{return !(*this < s);
}bool string::operator!=(const string& s)
{return !(*this == s);
}

7.查找:find 

(1)从pos位置开始向后查找字符c,返回c在string中第一次出现的位置,没找到返回npos

size_t string::find(char c, size_t pos) const
{assert(pos < _size);for (int i = pos; i < _size; ++i){if (_str[i] == c){return i;}}return npos;
}

(2)从pos位置开始向后查找字符串s,返回s在string中第一次出现的位置,没找到返回npos

size_t string::find(const char* s, size_t pos) const
{assert(pos < _size);const char* tmp = strstr(_str + pos, s);if (tmp == nullptr){return npos;}return tmp - _str;
}

8.在固定位置插入数据:insert

(1)在pos位置上插入字符c

string& string::insert(size_t pos, char c)
{assert(pos <= _size);if (_size == _capacity){// 扩容size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}//size_t end = _size + 1;//while (end > pos)//{//	_str[end] = _str[end - 1];//	end--;//}memmove(_str + pos + 1, _str + pos, _size - pos + 1);_str[pos] = c;_size++;return *this;
}

(2)在pos位置上插入字符串str

string& string::insert(size_t pos, const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){size_t newcapacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;reserve(newcapacity);}memmove(_str + pos + len, _str + pos, _size + 1 - pos);memcpy(_str + pos, str, len);_size += len;return *this;
}

9.删除固定位置的数据:erase

        当从pos位置开始要删除元素的个数大于剩余元素个数或等于npos时,将pos为之后的字符全部删除。

        当从pos位置开始要删除元素的个数小于剩余元素个数时,将要被删除的元素用后面的元素覆盖:

string& string::erase(size_t pos, size_t len)
{assert(pos < _size);if (len == npos || len >= _size - pos){_str[pos] = '\0';_size = pos;return *this;}memmove(_str + pos, _str + pos + len, _size + 1 - (pos + len));_size -= len;return *this;
}

10.流插入,流提取运算符重载:<<,>>

(1)流插入<<

std::ostream& operator<<(std::ostream& _cout, const my_string::string& s)
{for (int i = 0; i < s.size(); ++i){_cout << s[i];}return _cout;
}

(2)流提取>>

std::istream& operator>>(std::istream& _cin, my_string::string& s)
{// 每次提取前需要将s中的数据清除s.clear();// 模拟string中的buff缓冲区,当所输入的字符串有效数据个数小于256时,存放到buff中char buff[256];// 使用get函数,能够输入空白字符和换行符char ch = _cin.get();size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;ch = _cin.get();if (i == 255){s += buff;// 重置buffi = 0;}}// buff中有剩余字符if (i > 0){buff[i] = '\0';s += buff;}return _cin;
}

三.现代版写法的string类

1.构造函数

        用迭代器初始化string类:

template <class InputIterator>
string(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);++first;}
}

2.拷贝构造函数

// s2(s1)
string::string(const string& s)
{//string tmp(s._str);string tmp(s.begin(), s.end());swap(tmp);
}

        这里用s1的成员变量_str构造tmp,再将tmp和s2交换swap,这样tmp中的成员变量就与s2中的成员变量交换,出函数体后tmp同时也会被析构。

3.赋值重载

string& string::operator=(string tmp)
{swap(tmp);return *this;
}

四.代码总览 

string.h

#pragma once
#include<string.h>
#include<assert.h>
#include<iostream>namespace my_string
{class string{friend std::ostream& operator<<(std::ostream& _cout, const my_string::string& s);friend std::istream& operator>>(std::istream& _cin, my_string::string& s);public:typedef char* iterator;typedef const char* const_iterator;string(const char* str = ""):_size(strlen(str)){                                                              _str = new char[_size + 1];_capacity = _size;memcpy(_str, str, _size + 1);}string(const string& s){_str = new char[s._capacity + 1];memcpy(_str, s._str, s._size + 1);_size = s._size;_capacity = s._capacity;}string& operator=(const string& s){char* tmp = new char[s._capacity + 1];memcpy(tmp, s._str, s._size + 1);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}// iteratoriterator begin();iterator end();const_iterator begin() const;const_iterator end() const;// capacitysize_t size() const;size_t capacity() const;bool empty() const;void resize(size_t n, char c = '\0');void reserve(size_t n);// accesschar& operator[](size_t index);const char& operator[](size_t index) const;// relational operatorsbool operator<(const string& s);bool operator<=(const string& s);bool operator>(const string& s);bool operator>=(const string& s);bool operator==(const string& s);bool operator!=(const string& s);// modifyvoid push_back(char c);string& operator+=(char c);void append(const char* str);string& operator+=(const char* str);void clear();void swap(string& s);const char* c_str() const;// 返回c在string中第一次出现的位置size_t find(char c, size_t pos = 0) const;// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0) const;// 在pos位置上插入字符c/字符串str,并返回该字符的位置string& insert(size_t pos, char c);string& insert(size_t pos, const char* str);// 删除pos位置上的元素,并返回该元素的下一个位置string& erase(size_t pos, size_t len);private:char* _str;size_t _size;size_t _capacity;public:static const size_t npos;};
}

string.cpp

#include"string.h"namespace my_string
{const size_t string::npos = -1;std::ostream& operator<<(std::ostream& _cout, const my_string::string& s){for (int i = 0; i < s.size(); ++i){_cout << s[i];}return _cout;}std::istream& operator>>(std::istream& _cin, my_string::string& s){// 每次提取前需要将s中的数据清除s.clear();// 模拟string中的buff缓冲区,当所输入的字符串有效数据个数小于256时,存放到buff中char buff[256];// 使用get函数,能够输入空白字符和换行符char ch = _cin.get();size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;ch = _cin.get();if (i == 255){s += buff;// 重置buffi = 0;}}// buff中有剩余字符if (i > 0){buff[i] = '\0';s += buff;}return _cin;}const char* string::c_str() const{return _str;}size_t string::size() const{return _size;}size_t string::capacity() const{return _capacity;}string::iterator string::begin(){return _str;}string::iterator string::end(){return _str + _size;}string::const_iterator string::begin() const{return _str;}string::const_iterator string::end() const{return _str + _size;}bool string::empty() const{return _size == 0;}void string::resize(size_t n, char c){//if (n < _size)//{//	_str[n] = '\0';//	_size = n;//}//if (n > _size && n < _capacity)//{//	while (_size != n)//	{//		_str[_size++] = c;//	}//	_str[n] = '\0';//}//if (n > _capacity)//{//	(*this).reserve(n);//}if (n > _size){if (n > _capacity){reserve(n);}memset(_str + _size, c, n - _size);}_str[n] = '\0';_size = n;}void string::reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];memcpy(tmp, _str, _size + 1);delete[] _str;_str = tmp;_capacity = n;}}char& string::operator[](size_t index){return _str[index];}const char& string::operator[](size_t index) const{return _str[index];}bool string::operator<(const string& s){size_t end1 = _size - 1;size_t end2 = s._size - 1;size_t begin1 = 0;size_t begin2 = 0;while (begin1 != end1 && begin2 != end2){if (_str[begin1] < s._str[begin2]){return true;}else if (_str[begin1] > s._str[begin2]){return false;}begin1++;begin2++;}//if (begin1 == end1 && begin2 != end2)//{//	return true;//}//else//{//	return false;//}return begin1 == end1 && begin2 != end2;}bool string::operator==(const string& s){size_t end1 = _size - 1;size_t end2 = s._size - 1;size_t begin1 = 0;size_t begin2 = 0;while (begin1 != end1 && begin2 != end2){if (_str[begin1] != s._str[begin2]){return false;}begin1++;begin2++;}return begin1 == end1 && begin2 == end2;}bool string::operator<=(const string& s){return *this < s || *this == s;}bool string::operator>(const string& s){return !(*this <= s);}bool string::operator>=(const string& s){return !(*this < s);}bool string::operator!=(const string& s){return !(*this == s);}void string::push_back(char c){if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}_str[_size++] = c;_str[_size] = '\0';}void string::append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){size_t newcapacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;reserve(newcapacity);}memcpy(_str + _size, str, len + 1);_size += len;}string& string::operator+=(char c){push_back(c);return *this;}string& string::operator+=(const char* str){append(str);return *this;}void string::clear(){_str[0] = '\0';_size = 0;}void string::swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}size_t string::find(char c, size_t pos) const{assert(pos < _size);for (int i = pos; i < _size; ++i){if (_str[i] == c){return i;}}return npos;}size_t string::find(const char* s, size_t pos) const{assert(pos < _size);const char* tmp = strstr(_str + pos, s);if (tmp == nullptr){return npos;}return tmp - _str;}string& string::insert(size_t pos, char c){assert(pos <= _size);if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}//size_t end = _size + 1;//while (end > pos)//{//	_str[end] = _str[end - 1];//	end--;//}memmove(_str + pos + 1, _str + pos, _size - pos + 1);_str[pos] = c;_size++;return *this;}string& string::erase(size_t pos, size_t len){assert(pos < _size);if (len == npos || len >= _size - pos){_str[pos] = '\0';_size = pos;return *this;}memmove(_str + pos, _str + pos + len, _size + 1 - (pos + len));_size -= len;return *this;}string& string::insert(size_t pos, const char* str){size_t len = strlen(str);if (_size + len > _capacity){size_t newcapacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;reserve(newcapacity);}memmove(_str + pos + len, _str + pos, _size + 1 - pos);memcpy(_str + pos, str, len);_size += len;return *this;}
}

test.cpp

#include"string.h"
using namespace std;namespace my_string
{void Test_String1(){string s1("Hello world");cout << s1.c_str() << endl;                              cout << s1.size() << endl;           cout << s1.capacity() << endl;string s2 = "Hello";cout << s2.c_str() << endl;cout << s2.size() << endl;cout << s2.capacity() << endl;string s3(s2);cout << s3.c_str() << endl;cout << s3.size() << endl;cout << s3.capacity() << endl;string s4 = s1;cout << s4.c_str() << endl;cout << s4.size() << endl;cout << s4.capacity() << endl;s4 = s2;cout << s4.c_str() << endl;cout << s4.size() << endl;cout << s4.capacity() << endl;}void Test_String2(){string s1 = "Hello World";string::iterator it = s1.begin();while (it != s1.end()){(*it)++;cout << *it << ' ';++it;}cout << endl;const string s2(s1);string::const_iterator cit = s2.begin();while (cit != s2.end()){cout << *cit << ' ';++cit;}cout << endl;for (char e : s2){cout << e << ' ';}}void Test_String3(){string s1 = "Hello World";s1.reserve(100);cout << s1.c_str() << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1[0] << endl;++s1[0];cout << s1.c_str() << endl;string s2 = "Hello";s2.resize(2);cout << s2.c_str() << endl;cout << s2.size() << endl;cout << s2.capacity() << endl;s2.resize(4);cout << s2.c_str() << endl;cout << s2.size() << endl;cout << s2.capacity() << endl;s2.resize(10);cout << s2.c_str() << endl;cout << s2.size() << endl;cout << s2.capacity() << endl;//std::string s2 = "Hello";//s2.resize(2);//cout << s2.c_str() << endl;//cout << s2.size() << endl;//cout << s2.capacity() << endl;//s2.resize(4);//cout << s2.c_str() << endl;//cout << s2.size() << endl;//cout << s2.capacity() << endl;//s2.resize(10);//cout << s2.c_str() << endl;//cout << s2.size() << endl;//cout << s2.capacity() << endl;}void Test_String4(){string s1 = "Hello World";string s2 = "Hello";cout << (s1 < s2) << endl;cout << (s2 < s1) << endl;string s3(s1);cout << (s1 == s3) << endl;cout << (s2 == s3) << endl;cout << (s1 >= s2) << endl;cout << (s1 != s2) << endl;cout << (s2 <= s1) << endl;}void Test_String5(){string s1("Hello");s1.push_back('x');s1 += 'x';s1 += "xxxxx";cout << s1.c_str() << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;const char* p = "Worldxxxxxxx";string s3 = "Hello ";cout << s3.c_str() << endl;cout << s3.size() << endl;cout << s3.capacity() << endl;s3.append(p);cout << s3.c_str() << endl;cout << s3.size() << endl;cout << s3.capacity() << endl;string s4 = "Hello";string s5 = "Worldxxxxxxxx";cout << s4.c_str() << endl;cout << s4.size() << endl;cout << s4.capacity() << endl;cout << s5.c_str() << endl;cout << s5.size() << endl;cout << s5.capacity() << endl;s4.swap(s5);cout << s4.c_str() << endl;cout << s4.size() << endl;cout << s4.capacity() << endl;cout << s5.c_str() << endl;cout << s5.size() << endl;cout << s5.capacity() << endl;}void Test_String6(){string s1 = "Hello ";cout << s1.find('e') << endl;s1 += "World";cout << s1.find("Wor") << endl;cout << s1.c_str() << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;// "Hello World"s1.insert(0, 'x');cout << s1.c_str() << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;string s2 = "Hello World";//s2.erase(1, 2);s2.insert(11, "xxx");cout << s2.c_str() << endl;cout << s2.size() << endl;cout << s2.capacity() << endl;}void Test_String7(){string s1 = "Hello World";cout << s1 << endl;cin >> s1;cout << s1 << endl;}}int main()
{my_string::Test_String2();return 0;
}

http://www.dtcms.com/wzjs/72149.html

相关文章:

  • 网站建设与管理的实训广州网站推广服务
  • 移动端网站开发框架百度搜索引擎的特点
  • 网站用ai做还是pssem与seo的区别
  • 腾讯云主机网站建设教程关键词规划师
  • 建设交易平台网站多少钱全国人大常委会
  • 上位机软件开发教程优化方案英语
  • 在台湾做色聊的网站犯法不推广是做什么工作的
  • 专业的集团网站设计公司南宁seo咨询
  • 实体店做网站有用吗seo教程排名第一
  • dedecms制作网站教程企业文化建设
  • 温岭网站建设应用商店app下载
  • 商城网站建设二次开发苏州网站关键字优化
  • 网站管理员怎么做板块建设优秀的品牌策划案例
  • 网站一般采用的设计方案在线识图
  • 做ppt赚钱的网站网络营销项目策划书
  • 怎样做视频电影网站app投放渠道有哪些
  • 做网站关于创新的互联网公司
  • 1微信网站怎么建设成都官网seo服务
  • b2b网站对比深圳网络营销推广渠道
  • 旗县长安网站建设思路淘宝流量平台
  • wordpress能否做网站百度排行榜明星
  • 网站忧化技巧百度关键词推广一年多少钱
  • 自己做链接的网站亚洲精华国产精华液的护肤功效
  • 网站建设企业宣传口号谷歌海外广告投放推广
  • 做招聘网站公司网络营销推广的总结
  • 教育局网站建设管理工作意见推广代理平台
  • 购物网站开发教程 视频网站网址查询工具
  • 做网站费用 优帮云小说网站排名人气
  • 西安小程序河北seo技术交流
  • 烟台H5高端网站建设东莞seo网络培训