交换字符串C++中的单词

Swap words in string C++

本文关键字:单词 C++ 字符串 交换      更新时间:2024-09-28

我是一个新的StackOverflow用户! 我需要帮助。我的任务是在字符串中找到列表中的两个动词(_words[])并交换它们。使用字符串并不难实现,但我只允许使用char.

我的想法是这样的:我将char(char str[])数组拆分为单词,并将每个单词分配给一个常量数组(str2[]),我对已知动词做同样的事情。接下来,我检查 - 如果第一个数组中的单词与已知动词匹配,那么我将数字 (j) 分配给整数数组以了解该单词的位置。好吧,那么,在气泡方法的帮助下,我改变了它们的位置。但这很不走运,我查看了调试器,由于某种原因,在比较单词时,即使单词相同,检查也没有通过。 (对不起我的英语)

你能帮我弄清楚我做错了什么吗?我会很感激的!

#pragma warning(disable:4996)
#include <iostream>
#include <conio.h>
void words() {
char str[] = "i like to make programm";
char _words[] = "like make";
char* l1 = strtok(_words, " ");
const char* z[10]; 
const char* str2[10];
const char* temp[1];
int arr_num[2];
int i = 0, control = 0;
int word = 0;
char* stream;
while (l1 != NULL)
{
z[i] = l1;
l1 = strtok(NULL, " ");
i++;
}
for (int i = 0; i < 2; i++) {
cout << z[i] << endl;
}
i = 0;
for (int i = 0; i < strlen(str); i++) {
if (str[i] == ' ') {
word++;
}
}
word++;
stream = strtok(str, " ");
while (stream != NULL)
{
str2[i] = stream;
if(stream == z[0]) cout << "lol";
stream = strtok(NULL, " ");
i++;
}
for (int i = 0; i < word; i++) {
cout << str2[i] << endl;
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < word; j++) {
if ((z[i] == str2[j]) && (control < 3)) {
control++;
arr_num[i] = j;
}
}
}
if (control == 2) {
temp[0] = str2[arr_num[0]];
str2[arr_num[0]] = str2[arr_num[1]];
str2[arr_num[1]] = temp[0];
}
for (int i = 0; i < word; i++) {
cout << str2[i] << " ";
}
}

发布只是因为 OP 要求如何做到这一点的替代算法。还有其他方法,但这的好处是完全就地完成,除了一些指针和一些长度之外,不使用额外的存储空间。

此任务可以就地完成,方法是使用实用工具函数在给定指针和长度(或两个指针)的情况下反转字符序列。您还必须拥有许多其他可靠的操作,包括找到完整单词的能力。(例如,前面有空格或字符串开头,后面有空格或字符串结尾的单词。写下这些,并彻底测试它们。完成此操作后,请考虑以下事项。

字符串

this is a very simple sample of words

测试词

very of

我们首先将两个词分开,您已经在这样做了。接下来,我们使用经过良好测试的实用程序函数找到这两个词,记住它们的位置。我们知道它们的长度,因此我们可以计算它们的起点和终点。

this is a very simple sample of words
1111               22

旁注:执行此操作时,您会发现顺序可能向后。例如,如果您的单词列表是of very,那么结果将使您的单词位置如下所示:

this is a very simple sample of words
2222               11

没关系,重要的是,一旦你找到这两个单词,最接近字符串开头的单词是"第一个"单词,而后面出现的单词是从这里开始的"第二个"单词。

也就是说(现在回到我们原来的标签),从第一个单词的开头到第二个单词的结尾,将整个片段反转,不包括第一个单词之前或第二个单词之后的任何空格:

this is a fo elpmas elpmis yrev words
22               1111

接下来,在他们的新家就地颠倒这两个词。

this is a of elpmas elpmis very words
22               1111

最后,反转新第一个单词末尾之后的所有字符,直到(但不包括)新第二个单词的开头,包括空格这意味着这个区域:

this is a of elpmas elpmis very words
xxxxxxxxxxxxxxx

它变成了这样:

this is a of simple sample very words

这就是整个算法。一旦你找到了你的单词位置和范围,你实际上就是实现目标的四个很好的段逆转。显然,必须注意确保你不要在字符串开头之前,也不会超过字符串结尾,如果你被交换的单词位于这些位置。


更新:OP 提供的示例。

OP 提供了一个示例,显然不了解上述算法如何应用,所以我也通过该示例运行它

的话

like eat

感性

I like to eat apples

第 1 步:找到这两个词,注意它们的位置和长度。

I like to eat apples
1111    222

第2步:从第一个单词的开头到第二个单词的结尾反转整个片段。因此,下面标有"x"的段:

I like to eat apples
xxxxxxxxxxx

变成这样:

I tae ot ekil apples
222    1111

第 3 步:现在每个单词位于新位置,因此撤消它们

I eat ot like apples
222    1111

步骤4:反转两个单词之间的完整句段,包括空格。 例如,下面标记的段:

I eat ot like apples
xxxx

变成这样:

I eat to like apples

大功告成。