目标

对输入的字符串中的单词,把给定的索引区间中的单词逆序

方法一

  • 通过 strtok(strtok_s、strtok_r) 分割字符串
  • 使用 list 容器存储各个单词
  • 可以通过前插的方式反转指定区间的单词
  • 也可以通过前后交换的方式反转指定区间的单词
  • 顺序输出 list 中的单词
int main(){
    string str = "I am a developer";
	char *cArr = new char[str.size()+1]{0};
	strcpy_s(cArr, str.size()+1, str.c_str());	// 注意:第二个参数,要拷贝的字符串的长度包括结尾的 '\0'
	char *w = nullptr, *rest = nullptr;
	list<string> wordList;
	w = strtok_s(cArr, " ", &rest);
	while (w)
	{
		wordList.push_back(w);
		w = strtok_s(nullptr, " ", &rest);
	}
	int startIndex = 0, endIndex = 0;
	cin >> startIndex >> endIndex;
	int len = wordList.size();
	if (endIndex > startIndex && startIndex < len - 1) {
		startIndex = startIndex > -1 ? startIndex : 0;
		endIndex = endIndex > len - 1 ? len - 1 : endIndex;
		int i = 0;
		list<string>::iterator itr = wordList.begin(), startItr = itr, endItr = itr;
		// 方法一:通过前插,然后删除的方式
		/*
		for (itr = wordList.begin(); itr != wordList.end(); ++itr, ++i) {
			if (i == startIndex) {
				startItr = itr;
				++i;
				++itr;
				break;
			}
		}
		while (i > startIndex && i <= endIndex)
		{
			wordList.insert(startItr, *itr);
			itr = wordList.erase(itr);
			startItr--;
			++i;
		}
		*/
		// 方法二:通过交换的方式
		for (; itr != wordList.end(); ++itr, ++i) {
			if (i == startIndex) {
				startItr = itr;
			}else if(i == endIndex){
			    endItr = itr;
			    break;
			}
		}
		int step = endIndex - startIndex;
		for(i = 0; i <= step / 2 && startItr != endItr; ++i){
		    string tmp = *startItr;
		    *startItr = *endItr;
		    *endItr = tmp;
			// 等同于下面的函数调用
			// iter_swap(startItr, endItr);
		    startItr++;
		    endItr--;
		}
	}
	for (auto word : wordList) {
		cout << word << " ";
	}

	delete[] cArr;
    return 0;
}

方法二

  • 通过 substring 提取单词
  • 使用 vector 存储分割的单词
  • 逆序输出指定区间中的单词
int main()
{
	string str = "I am a developer";
	vector<string> words;
	str += " ";
	size_t startPos = 0, endPos = 0;
	endPos = str.find(' ', startPos);
	while (endPos != string::npos) {
		words.push_back(str.substr(startPos, endPos - startPos));
		startPos = endPos + 1;
		endPos = str.find(' ', startPos);
	}

	int beginIndex = 0, endIndex = 0;
	cin >> beginIndex >> endIndex;
	int len = words.size();		// 注意:此处返回的类型是 unsigned int,与负数比较会有问题
	if (endIndex > beginIndex && beginIndex < len-1)
	{
		beginIndex = beginIndex > -1 ? beginIndex : 0;
		endIndex = endIndex >= len ? len - 1 : endIndex;

		for (int i = 0; i < words.size(); ++i)
		{
			if (i >= beginIndex && i <= endIndex)
			{
				cout << words[endIndex - (i - beginIndex)] << " ";
			}
			else
			{
				cout << words[i] << " ";
			}
		}
	}
	else
	{
		cout << str;
	}

	return 0;
}