交换字符串 C++ 中的单词
Swap words in string C++
我是 Whosebug 的新用户!我需要帮助。我的任务是在字符串中找到列表中的两个动词 (_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 要求提供一种替代算法来完成此操作。还有其他方法,但这具有完全就地完成的好处,除了一些指针和一些长度之外不使用额外的存储。
这个任务可以完成 in-place,通过使用一个实用函数来反转字符序列,给定一个指针和长度(或两个指针)。您还必须拥有许多其他可靠 操作,包括查找完整 单词的能力。 (例如,前面是空格或 begin-of-string,后面是空格或 end-of-string 的单词。写下这些,然后 彻底测试 。一旦你完成了, 请考虑以下内容。
字符串
this is a very simple sample of words
测试词
very of
我们首先将两个词分开,您已经这样做了。接下来我们找到这两个词,记住它们的位置,使用你的 well-tested 实用函数。我们知道它们的长度,因此我们可以计算它们的起点和终点。
this is a very simple sample of words
1111 22
旁注:执行此操作时,您会发现 order 可能落后。例如,如果您的单词列表是 of very
,那么结果中您的单词位置将如下所示:
this is a very simple sample of words
2222 11
没关系,重要的是一旦你找到两个词,最接近字符串开头的词是“第一个”词,后面的是“第二个”词出来了。
也就是说(现在回到我们原来的标签),从第一个单词的开头到第二个单词的结尾反转整个片段,不包括任何空格在第一个之前,或在第二个之后:
this is a fo elpmas elpmis yrev words
22 1111
接下来在他们的新家把两个字in-place反过来
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
这就是整个算法。一旦找到单词的位置和范围,您就可以完成四个 well-place 段反转来实现您的目标。显然,必须注意确保您不在字符串开头之前,也不超过 end-of-string,如果您要交换的单词位于这些位置。
更新:OP-provided样本。
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
大功告成。
我是 Whosebug 的新用户!我需要帮助。我的任务是在字符串中找到列表中的两个动词 (_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 要求提供一种替代算法来完成此操作。还有其他方法,但这具有完全就地完成的好处,除了一些指针和一些长度之外不使用额外的存储。
这个任务可以完成 in-place,通过使用一个实用函数来反转字符序列,给定一个指针和长度(或两个指针)。您还必须拥有许多其他可靠 操作,包括查找完整 单词的能力。 (例如,前面是空格或 begin-of-string,后面是空格或 end-of-string 的单词。写下这些,然后 彻底测试 。一旦你完成了, 请考虑以下内容。
字符串
this is a very simple sample of words
测试词
very of
我们首先将两个词分开,您已经这样做了。接下来我们找到这两个词,记住它们的位置,使用你的 well-tested 实用函数。我们知道它们的长度,因此我们可以计算它们的起点和终点。
this is a very simple sample of words
1111 22
旁注:执行此操作时,您会发现 order 可能落后。例如,如果您的单词列表是 of very
,那么结果中您的单词位置将如下所示:
this is a very simple sample of words
2222 11
没关系,重要的是一旦你找到两个词,最接近字符串开头的词是“第一个”词,后面的是“第二个”词出来了。
也就是说(现在回到我们原来的标签),从第一个单词的开头到第二个单词的结尾反转整个片段,不包括任何空格在第一个之前,或在第二个之后:
this is a fo elpmas elpmis yrev words
22 1111
接下来在他们的新家把两个字in-place反过来
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
这就是整个算法。一旦找到单词的位置和范围,您就可以完成四个 well-place 段反转来实现您的目标。显然,必须注意确保您不在字符串开头之前,也不超过 end-of-string,如果您要交换的单词位于这些位置。
更新:OP-provided样本。
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
大功告成。