最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++模擬實(shí)現(xiàn)string的示例代碼

 更新時(shí)間:2022年11月17日 08:18:45   作者:蔣靈瑜的筆記本  
這篇文章主要為大家詳細(xì)介紹了C++模擬實(shí)現(xiàn)string的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定的幫助,需要的可以參考一下

一、std::swap和std::string::swap的區(qū)別

如果用std::swap交換兩個(gè)string對(duì)象,將會(huì)發(fā)生1次構(gòu)造和2次賦值,也就是三次深拷貝;而使用std::string::swap僅交換成員,代價(jià)較小。

二、string的默認(rèn)構(gòu)造函數(shù)

1、構(gòu)造函數(shù)

string(const char* s = "")
{
    _size = strlen(s);//_size和_capacity均不包含'\0'
    _capacity = _size;
    _arr = new char[_size + 1];
    memcpy(_arr, s, _size + 1);
}

構(gòu)造函數(shù)用缺省值,能夠滿(mǎn)足空串的構(gòu)造。

這里設(shè)計(jì)_size和_capacity均不包含'\0'。_arr的空間多new一個(gè),用于儲(chǔ)存'\0'。

再將形參的內(nèi)存拷貝至_arr中,即可完成構(gòu)造。

2、拷貝構(gòu)造

寫(xiě)法1:老老實(shí)實(shí)的根據(jù)string對(duì)象的私有變量進(jìn)行拷貝構(gòu)造。

string(const string& s)
{
    _size = s._size;//_size和_capacity均不包含'\0'
    _capacity = s._capacity;
    _arr = new char[_capacity + 1];
    memcpy(_arr, s._arr, _capacity + 1);
}

寫(xiě)法2:通過(guò)構(gòu)造一個(gè)臨時(shí)對(duì)象,將這個(gè)臨時(shí)對(duì)象的私有變量全部和*this的私有變量交換。

注意拷貝構(gòu)造需要先將_arr初始化為nullptr,防止后續(xù)tmp拿到隨機(jī)地址。(tmp銷(xiāo)毀將調(diào)用析構(gòu)函數(shù),對(duì)一塊隨機(jī)地址的空間進(jìn)行析構(gòu)程序?qū)?huì)崩潰)

void swap(string& s)
{
    std::swap(_arr, s._arr);
    std::swap(_size, s._size);
    std::swap(_capacity, s._capacity);
}
string(const string& s)
    :_arr(nullptr)//防止交換后tmp._arr為隨機(jī)值,析構(gòu)出錯(cuò)
{
    string tmp(s.c_str());//構(gòu)造
    swap(tmp);
}

3、賦值運(yùn)算符重載

寫(xiě)法1:同樣的老實(shí)人寫(xiě)法。這種寫(xiě)法要防止自己給自己賦值!

string& operator=(const string& s)
{
    if (this != &s)//防止自己給自己賦值
    {
        _size = s._size;
        _capacity = s._capacity;
        char* tmp = new char[_capacity + 1];
        delete[] _arr;
        _arr = tmp;
        memcpy(_arr, s._arr, _capacity + 1);
    }
    return *this;
}

寫(xiě)法2:通過(guò)構(gòu)造臨時(shí)變量tmp,完成賦值。這種寫(xiě)法無(wú)需擔(dān)心自己給自己賦值的情況,并且_arr無(wú)需初始化為nullptr。 

void swap(string& s)
{
    std::swap(_arr, s._arr);
    std::swap(_size, s._size);
    std::swap(_capacity, s._capacity);
}
string& operator=(const string& s)
{
    string tmp(s.c_str());//構(gòu)造
    swap(tmp);
    return *this;
}

4、析構(gòu)函數(shù)

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

三、string中的小接口

//string的size()接口
size_t size()const//右const修飾*this,這樣const和非const對(duì)象均可調(diào)用
{
    return _size;
}
//string的c_str()接口
const char* c_str()const
{
    return _arr;
}
//string的capacity()接口
size_t capacity()const
{
    return _capacity;
}
//string的clear()接口
void clear()
{
    _arr[0] = '\0';
    _size = 0;
}
//string的判空
bool empty()const
{
    return _size == 0 ? false : true;
}

如果函數(shù)形參不發(fā)生改變的,無(wú)腦加const修飾。

只有指針和引用會(huì)有const權(quán)限問(wèn)題。

四、遍歷接口的實(shí)現(xiàn)

1、對(duì)operator[]進(jìn)行重載

char& operator[](size_t pos)//普通對(duì)象,可讀可寫(xiě)
{
    assert(pos < _size);
    return _arr[pos];
}
const char& operator[](size_t pos)const//const對(duì)象,僅讀
{
    assert(pos < _size);
    return _arr[pos];
}

讓字符串進(jìn)行下標(biāo)式的訪問(wèn),需要重載兩個(gè)operator[]函數(shù),正常對(duì)象去調(diào)可讀可寫(xiě),const對(duì)象調(diào)用只讀。

2、迭代器

typedef char* iterator;
iterator begin()
{
    return _arr;
}
iterator end()//end指向字符串的'\0'
{
    return _arr + _size;
}

string的迭代器是字符指針,寫(xiě)完迭代器就可以用迭代器實(shí)現(xiàn)訪問(wèn)、修改了。

范圍for的底層也是一個(gè)迭代器,但是范圍for底層只認(rèn)begin()和end(),如果和自己實(shí)現(xiàn)的迭代器接口名稱(chēng)對(duì)不上,那么范圍for將無(wú)法使用。

五、reserve和resize

//sring的reserve接口, 如果預(yù)開(kāi)空間小于現(xiàn)有空間,將不會(huì)改變?nèi)萘俊?
void reserve(size_t n = 0)
{
    if (n + 1 > _capacity)
    {
        char* tmp = new char[n + 1];
        memset(tmp, '\0', n + 1);
        memcpy(tmp, _arr, _size);
        delete[] _arr;
        _arr = tmp;
        _capacity = n;
    }
}
//sring的resize接口
void resize(size_t n, char c)
{
    //判斷n的大小
    if (n > _capacity)
    {
        reserve(n);
        memset(_arr + _size, c, n - _size);
        _size = n;
    }
    else
    {
        _arr[n] = '\0';
        _size = n;
    }
}

reserve是擴(kuò)容,可以用于預(yù)開(kāi)空間,防止頻繁的空間申請(qǐng)。申請(qǐng)一塊n+1大小的空間,將該空間全部初始化'\0',再將_arr中的數(shù)據(jù)拷貝至tmp中,釋放_(tái)arr,_arr指向tmp。

在resize中需要考慮_size擴(kuò)容和縮容的問(wèn)題。

六、插入刪除查找相關(guān)接口

1、push_back、append、+=

string& push_back(const char c)
{
    //判斷容量
    if (_size == _capacity)
    {
        size_t newCapacity = _capacity == 0 ? 4 : _capacity * 2;//防止出現(xiàn)空串的情況
        reserve(newCapacity);
    }
    _arr[_size++] = c;
    return *this;
}
string& append(const char* s)
{
    //判斷容量
    size_t len = strlen(s);
    if (_size + len > _capacity)
    {
        reserve(_size + len);
    }
    strcpy(_arr + _size, s);
    _size += len;
    return *this;
}
string& operator+=(const char c)
{
    push_back(c);
    return *this;
}
string& operator+=(const char* s)
{
    append(s);
    return *this;
}

寫(xiě)push_back要考慮到原對(duì)象為空串的情況(即_capacity為0)。

+=可以復(fù)用push_back和append。

2、insert和earse

string& insert(size_t pos, char c)
{
    assert(pos < _size);
    //判斷容量
    if (_size == _capacity)
    {
        reserve(_capacity + 1);
    }
    //挪動(dòng)數(shù)據(jù)
    for (size_t i = _size; i > pos; --i)
    {
        _arr[i] = _arr[i - 1];
    }
    _arr[pos] = c;
    ++_size;
    return *this;
}
string& insert(size_t pos, const char* s)
{
    size_t len = strlen(s);
    //判斷容量
    if (len + _size > _capacity)
    {
        reserve(len + _size);
    }
    //挪動(dòng)數(shù)據(jù)
    for (size_t i = _size + len; i > pos + len - 1; --i)
    {
        _arr[i] = _arr[i - len];
    }
    memcpy(_arr + pos, s, len);
    _size += len;
    return *this;
}
string& earse(size_t pos, size_t len = npos)
{
    assert(pos < _size);
    //先判斷刪到底的情況
    if (len == npos || pos + len >= _size)
    {
        _arr[pos] = '\0';
        _size = pos;
    }
    else
    {
        memcpy(_arr + pos, _arr + pos + len, _size - pos - len);
        _size -= len;
    }
    return *this;
}

insert接口在挪動(dòng)數(shù)據(jù)時(shí),從最后一個(gè)元素的后一個(gè)(后len個(gè))位置開(kāi)始覆蓋,可以保證不出現(xiàn)size_t 類(lèi)型越界的情況。

earse接口,需要分類(lèi)討論字符串是否刪到底。

注意,這個(gè)pos是const static成員,C++語(yǔ)法中,只有指針和整型的const static成員是可以在類(lèi)中進(jìn)行初始化的。

3、find

size_t find(const char c, size_t pos = 0)const
{
    assert(pos < _size);
    for (size_t i = pos; i < _size; ++i)
    {
        if (_arr[i] == c)
        {
            return i;
        }
    }
    return npos;
}
size_t find(const char* s, size_t pos = 0)const
{
    assert(pos < _size);
    const char* p = strstr(_arr, s);
    if (p != nullptr)
    {
        return _arr - p;
    }
    return npos;
}

從指定位置找字符或字符串,找到了,返回第一個(gè)匹配字符/子串的下標(biāo)。

七、流插入和流提取

//流插入和流提取的重載時(shí)為了自定義類(lèi)型的輸入輸出
inline ostream& operator<<(ostream& out, const string& s)//這里訪問(wèn)的到私有,所以可以不用寫(xiě)成友元函數(shù)
{
    for (size_t i = 0; i < s.size(); ++i)//流插入按照_size打印,c_str找到'\0'結(jié)束打印
    {                                    //比如我在字符串中間插入一個(gè)'\0',打印結(jié)果不一樣
        out << s[i];
    }
    return out;
}
inline istream& operator>>(istream& in, string& s)
{
    s.clear();//用之前先清空s
    //in >> c;//流提取不會(huì)識(shí)別空格和換行
    char c = in.get();
    char buff[128] = { '\0' };//防止頻繁擴(kuò)容
    size_t i = 0;
    while (c != ' ' && c != '\n')
    {
        if (i == 127)
        {
            s += buff;
            i = 0;
        }
        buff[i++] = c;
        c = in.get();
    }
    if (i > 0)
    {
        buff[i] = '\0';
        s += buff;
    }
    return in;
}

因?yàn)閟tring提供了訪問(wèn)私有的接口,所以流插入和流提取可以不用重載成string類(lèi)的友元函數(shù)。

對(duì)于流提取,如果頻繁的尾插,會(huì)造成頻繁擴(kuò)容。而且C++的擴(kuò)容和C語(yǔ)言的擴(kuò)容不一樣,C++使用new不能原地?cái)U(kuò)容,只能異地?cái)U(kuò)容,異地?cái)U(kuò)容就會(huì)導(dǎo)致新空間的開(kāi)辟、數(shù)據(jù)的拷貝、舊空間釋放。為了防止頻繁擴(kuò)容,我們可以創(chuàng)建一個(gè)可以存儲(chǔ)128字節(jié)的數(shù)組,在這個(gè)數(shù)組中操作,這個(gè)數(shù)組滿(mǎn)了就尾插至對(duì)象s中。

為什么不能用getline,而是要一個(gè)字符一個(gè)字符尾插呢?因?yàn)榱魈崛∮龅娇崭窈?#39;\n'會(huì)結(jié)束提取,剩余數(shù)據(jù)暫存緩沖區(qū),如果是getline的話,遇到空格是不會(huì)停止讀取的。

八、模擬實(shí)現(xiàn)的string整體代碼

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
using std::cout;
using std::cin;
using std::endl;
using std::ostream;
using std::istream;
namespace jly
{
	class string
	{
	public:
		void swap(string& s)
		{
			std::swap(_arr, s._arr);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		//構(gòu)造函數(shù)
		string(const char* s = "")
		{
			_size = strlen(s);//_size和_capacity均不包含'\0'
			_capacity = _size;
			_arr = new char[_size + 1];
			memcpy(_arr, s, _size + 1);
		}
		//拷貝構(gòu)造
		//寫(xiě)法1
		//string(const string& s)
		//{
		//	_size = s._size;//_size和_capacity均不包含'\0'
		//	_capacity = s._capacity;
		//	_arr = new char[_capacity + 1];
		//	memcpy(_arr, s._arr, _capacity + 1);
		//}
		//寫(xiě)法2
		string(const string& s)
			:_arr(nullptr)//防止交換后tmp._arr為隨機(jī)值,析構(gòu)出錯(cuò)
		{
			string tmp(s.c_str());//構(gòu)造
			swap(tmp);
		}
		//賦值運(yùn)算符重載
		//寫(xiě)法1
		//string& operator=(const string& s)
		//{
		//	if (this != &s)//防止自己給自己賦值
		//	{ 
		//		_size = s._size;
		//		_capacity = s._capacity;
		//		char* tmp = new char[_capacity + 1];
		//		delete[] _arr;
		//		_arr = tmp;
		//		memcpy(_arr, s._arr, _capacity + 1);
		//	}
		//	return *this;
		//}
		//寫(xiě)法2
		string& operator=(const string& s)
		{
			string tmp(s.c_str());//構(gòu)造
			swap(tmp);
			return *this;
		}
		//析構(gòu)函數(shù)
		~string()
		{
			_size = _capacity = 0;
			delete[] _arr;
			_arr = nullptr;
		}
		//string的size()接口
		size_t size()const//右const修飾*this,這樣const和非const對(duì)象均可調(diào)用
		{
			return _size;
		}
		//string的c_str()接口
		const char* c_str()const
		{
			return _arr;
		}
		//string的capacity()接口
		size_t capacity()const
		{
			return _capacity;
		}
		//string的clear()接口
		void clear()
		{
			_arr[0] = '\0';
			_size = 0;
		}
		//string的判空
		bool empty()const
		{
			return _size == 0 ? false : true;
		}
		//對(duì)operator[]進(jìn)行重載
		char& operator[](size_t pos)//普通對(duì)象,可讀可寫(xiě)
		{
			assert(pos < _size);
			return _arr[pos];
		}
		const char& operator[](size_t pos)const//const對(duì)象,僅讀
		{
			assert(pos < _size);
			return _arr[pos];
		}
		//迭代器
		typedef char* iterator;
		iterator begin()const
		{
			return _arr;
		}
		iterator end()const//end指向字符串的'\0'
		{
			return _arr + _size ;
		}
		//string的reserve接口,如果預(yù)開(kāi)空間小于現(xiàn)有空間,將不會(huì)改變?nèi)萘俊?
		void reserve(size_t n=0)
		{
			if (n + 1 > _capacity)
			{
				char* tmp = new char[n + 1];
				memset(tmp, '\0', n + 1);
				memcpy(tmp, _arr, _size);
				delete[] _arr;
				_arr = tmp;
				_capacity = n;
			}
		}
		//string的resize接口
		void resize(size_t n, char c='\0')
		{
			//判斷n的大小
			if (n > _capacity)
			{
				reserve(n);
				memset(_arr + _size,c,n-_size);
				_size = n;
			}
			else
			{
				_arr[n] = '\0';
				_size = n;
			}
		}
		//插入刪除查找相關(guān)接口
		string& push_back(const char c)
		{
			//判斷容量
			if (_size == _capacity)
			{
				size_t newCapacity = _capacity == 0 ? 4 : _capacity * 2;//防止出現(xiàn)空串的情況
				reserve(newCapacity);
			}
			_arr[_size++] = c;
			return *this;
		}
		string& append(const char* s)
		{
			//判斷容量
			size_t len = strlen(s);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			strcpy(_arr+_size,s);
			_size += len;
			return *this;
		}
		string& operator+=(const char c)
		{
			push_back(c);
			return *this;
		}
		string& operator+=(const char* s)
		{
			append(s);
			return *this;
		}
		string& insert(size_t pos, char c)
		{
			assert(pos < _size);
			//判斷容量
			if (_size == _capacity)
			{
				reserve(_capacity + 1);
			}
			//挪動(dòng)數(shù)據(jù)
			for (size_t i = _size; i > pos; --i)
			{
				_arr[i] = _arr[i - 1];
			}
			_arr[pos] = c;
			++_size;
			return *this;
		}
		string& insert(size_t pos, const char* s)
		{
			size_t len = strlen(s);
			//判斷容量
			if (len + _size > _capacity)
			{
				reserve(len + _size);
			}
			//挪動(dòng)數(shù)據(jù)
			for (size_t i = _size + len; i > pos + len - 1; --i)
			{
				_arr[i] = _arr[i - len];
			}
			memcpy(_arr + pos, s, len);
			_size += len;
			return *this;
		}
		string& earse(size_t pos, size_t len = npos)
		{
			assert(pos<_size);
			//先判斷刪到底的情況
			if (len == npos || pos + len >= _size)
			{
				_arr[pos] = '\0';
				_size = pos;
			}
			else
			{
				memcpy(_arr + pos, _arr + pos + len,_size-pos-len);
				_size -= len;
			}
			return *this;
		}
		size_t find(const char c, size_t pos = 0)const
		{
			assert(pos < _size);
			for (size_t i = pos; i < _size; ++i)
			{
				if (_arr[i] == c)
				{
					return i;
				}
			}
			return npos;
		}
		size_t find(const char* s, size_t pos = 0)const
		{
			assert(pos < _size);
			const char* p = strstr(_arr, s);
			if (p != nullptr)
			{
				return _arr - p;
			}
			return npos;
		}
	private:
		char* _arr;
		size_t _size;
		size_t _capacity;
		const static size_t npos = -1;//只有const static整型、指針成員變量可以在類(lèi)中定義,其他類(lèi)型不行
	};
	//流插入和流提取的重載時(shí)為了自定義類(lèi)型的輸入輸出
	inline ostream& operator<<(ostream& out, const string& s)//這里訪問(wèn)得到私有,所以可以不用寫(xiě)成友元函數(shù)
	{
		for (size_t i = 0; i < s.size(); ++i)//流插入按照_size打印,c_str找到'\0'結(jié)束打印
		{                                    //比如我在字符串中間插入一個(gè)'\0',打印結(jié)果不一樣
			out << s[i];
		}
		return out;
	}
	inline istream& operator>>(istream& in, string& s)
	{
		s.clear();//用之前先清空s
		//in >> c;//流提取不會(huì)識(shí)別空格和換行
		char c=in.get();
		char buff[128] = { '\0' };//防止頻繁擴(kuò)容
		size_t i = 0;
		while (c != ' ' && c != '\n')
		{
			if (i == 127)
			{
				s += buff;
				i = 0;
			}
			buff[i++] = c;
			c = in.get();
		}
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}
	//測(cè)試函數(shù)
	void test1()
	{
	
	}
}

以上就是C++模擬實(shí)現(xiàn)string的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于C++實(shí)現(xiàn)string的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)和雙向鏈表操作

    C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)和雙向鏈表操作

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)雙向鏈表操作,需要的朋友可以參考下
    2017-03-03
  • C語(yǔ)言歸排與計(jì)排深度理解

    C語(yǔ)言歸排與計(jì)排深度理解

    這篇文章主要為大家詳細(xì)的介紹了C語(yǔ)言中計(jì)數(shù)排序和歸并排序,歸并排序是創(chuàng)建在歸并操作上的一種有效的排序算法,計(jì)數(shù)排序不用比較兩個(gè)數(shù)的大小,感興趣的朋友可以參考閱讀
    2023-04-04
  • 使用C++的inipp庫(kù)處理配置文件.ini的示例詳解

    使用C++的inipp庫(kù)處理配置文件.ini的示例詳解

    一個(gè)ini文件由多個(gè)節(jié)section組成,每個(gè)節(jié)由多個(gè)鍵值對(duì)組成,本文給大家介紹了使用第三方庫(kù)inipp來(lái)操作ini文件,文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Qt服務(wù)應(yīng)用操作之JSON文件操作方法

    Qt服務(wù)應(yīng)用操作之JSON文件操作方法

    在Qt框架中,處理JSON數(shù)據(jù)包括解析、生成、保存和讀取文件等操作,本文詳細(xì)介紹了這些操作的關(guān)鍵類(lèi)和方法,如QJsonDocument、QJsonObject、QJsonArray等,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • Visual Studio 2022配置fftw第三方庫(kù)的詳細(xì)過(guò)程

    Visual Studio 2022配置fftw第三方庫(kù)的詳細(xì)過(guò)程

    FFTW是一個(gè)可以進(jìn)行可變長(zhǎng)度一維或多維DFT的開(kāi)源C程序庫(kù),是目前最快的FFT算法實(shí)現(xiàn),本文簡(jiǎn)述了在Windows平臺(tái)上,如何在C++中調(diào)用FFTW,所使用的IDE為Visual Studio 2022,感興趣的朋友一起看看吧
    2024-06-06
  • 一篇文章帶你了解C++中的異常

    一篇文章帶你了解C++中的異常

    這篇文章主要為大家詳細(xì)介紹了C++中的異常,使用數(shù)據(jù)庫(kù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • VS2017開(kāi)發(fā)C語(yǔ)言出現(xiàn)“no_init_all“的解決辦法

    VS2017開(kāi)發(fā)C語(yǔ)言出現(xiàn)“no_init_all“的解決辦法

    這篇文章介紹了VS2017開(kāi)發(fā)C語(yǔ)言出現(xiàn)“no_init_all“的解決辦法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • C++中delete和delete[]的區(qū)別

    C++中delete和delete[]的區(qū)別

    這篇文章主要介紹了C++中delete和delete[]的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • C++?超詳細(xì)示例講解list的使用

    C++?超詳細(xì)示例講解list的使用

    list是一種序列式容器。list容器完成的功能實(shí)際上和數(shù)據(jù)結(jié)構(gòu)中的雙向鏈表是極其相似的,list中的數(shù)據(jù)元素是通過(guò)鏈表指針串連成邏輯意義上的線性表,也就是list也具有鏈表的主要優(yōu)點(diǎn),即:在鏈表的任一位置進(jìn)行元素的插入、刪除操作都是快速的
    2022-07-07
  • Qt實(shí)現(xiàn)繪制多個(gè)設(shè)備的流量曲線圖詳解

    Qt實(shí)現(xiàn)繪制多個(gè)設(shè)備的流量曲線圖詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Qt開(kāi)發(fā)繪制多個(gè)設(shè)備的流量曲線圖,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,需要的可以參考一下
    2023-01-01

最新評(píng)論

萨迦县| 广德县| 左权县| 平原县| 崇阳县| 武强县| 西和县| 壶关县| 荔浦县| 锡林浩特市| 同江市| 体育| 宁乡县| 新河县| 吉水县| 富源县| 即墨市| 盐池县| 邢台市| 阜阳市| 黄平县| 沭阳县| 滨州市| 北辰区| 建平县| 泰兴市| 金华市| 尼木县| 五指山市| 太仆寺旗| 旬阳县| 普安县| 洛阳市| 张家港市| 石泉县| 阜阳市| 大英县| 姜堰市| 富源县| 土默特右旗| 清水河县|