在阵列中向上移动对象
Shifting Objects Up in an Array
我正在创建一个程序,该程序在数组大小为 8 的随机位置创建一个对象数组。创建后,我需要它们进行排序,以便数组中的所有对象都移动到顶部,因此它们之间不存在间隙。我快到了,但我似乎无法让它们交换到数组中的索引 0,而是交换到索引 1。有什么建议吗?(必须按照我的方式完成,而不是使用其他排序算法或其他方式)
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
struct WordCount {
string name = "";
int count = 0;
};
int main() {
cout << "Original random array: " << endl;
srand(static_cast<int>(time(0)));
int i = 0;
WordCount wordArr[8];
while (i < 4) {
int randomNum = 0 + (rand() % static_cast<int>(7 + 1));
if(wordArr[randomNum].name == "") {
wordArr[randomNum].name = "word" + static_cast<char>(i);
wordArr[randomNum].count = i;
i++;
}
}
int j = 0;
while (j < 8) {
cout << wordArr[j].name << " " << wordArr[j].count << endl;
j++;
}
cout << "nnSorted array: " << endl;
for (int i = 7; i >= 0; i--) {
for (int j = 0; j <= 7; j++) {
if (wordArr[i].name != "") {
if (wordArr[j].name == "") {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
}
int k = 0;
while (k < 8) {
cout << wordArr[k].name << " " << wordArr[k].count << endl;
k++;
}
return 0;
}
如果我正确理解您的要求,您希望将所有非空白条目移动到数组的开头。为此,您需要这样的算法,例如:
for i = 0 to 7
if wordArr[i].name is blank
for j = i + 1 to 7
if wordArr[j].name is not blank
swap [i] and [j]
break
因此,从头开始,如果我们遇到空白条目,我们期待下一个非空白条目。如果我们找到这样的条目,我们交换空白和非空白条目,然后中断再次循环寻找下一个空白条目。
请注意,这不是最有效的解决方案,但它会让您入门。
另请注意,我将 4 和 8 替换为以下定义:
#define MAX_ENTRIES (8)
#define TO_GENERATE_ENTRIES (4)
最后:
wordArr[randomNum].name = "word" + static_cast<char>(i);
这不会做你想要它做的事情;试试:
wordArr[randomNum].name = "word" + static_cast<char>('0' + i);
将数字(而不是字节代码)附加到数字的末尾。或者,如果您有 C++11:
wordArr[randomNum].name = "word" + std::to_string(i);
我看到了几个问题。
-
表达式
"word" + static_cast<char>(i);
不会做您希望做的事情。它相当于:
char const* w = "word"; char const* p = w + i;
当
i
为 2 时,p
将"rd"
。您需要使用std::string("word") + std::to_string(i)
. -
将具有非空名称的对象移动到具有空名称的对象的逻辑对我来说没有意义。它显然不适合你。以下更新版本对我有用:
for (int i = 0; i <= 7; ++i) { // If the name of the object at wordArr[i] is not empty, move on to the // next item in the array. If it is empty, copy the next object that // has a non-empty name. if ( wordArr[i].name == "") { // Start comparing from the object at wordArr[i+1]. There // is no need to start at wordArr[i]. We know that it is empty. for (int j = i+1; j <= 7; ++j) { if (wordArr[j].name != "") { WordCount temp = wordArr[i]; wordArr[i] = wordArr[j]; wordArr[j] = temp; } } } }
有两个问题:
-
wordArr[randomNum].name = "word" + static_cast<char>(i);
这不是您要找的,如果您希望您的名称正确生成,则需要这样的东西:wordArr[randomNum].name = "word " + std::to_string(i);
-
您的排序循环没有做您想要的,它只是检查您所说的"间隙",您需要这样的东西:
for (int i = 0; i < 8; ++i) { for (int j = i+1; j < 8; ++j) { if (wordArr[i].name == "" || (wordArr[i].count < wordArr[j].count)) { WordCount temp = wordArr[i]; wordArr[i] = wordArr[j]; wordArr[j] = temp; } } }
您的算法对数组进行排序,但随后再次丢失排序。
您希望仅在i > j
时交换元素,以便仅将元素推到顶部。因此,您需要更改此设置:
if (wordArr[j].name == "")
对此:
if (wordArr[j].name == "" && i > j)
请考虑以下数组示例:
0
ord 1
0
0
rd 2
word 0
d 3
0
您的代码会将其排序为:
d 3
ord 1
word 0
rd 2
0
0
0
0
但是当 i = 3
,它将尝试填充第 5 个单元格,并将其与 rd 2
交换,这不是我们想要的。
这会rd 2
向下推,但我们不希望这样,我们希望间隙(零)进入数组的末尾,因此我们只需要在它们要走高而不是更低时才交换 eleemnts,这相当于说当i > j
时。
PS:如果您是初学者,请跳过该部分。
您可以使用一个 if 语句和一个 break 关键字来优化内部循环,如下所示:
for (int j = 0; j <= 7; j++) {
if (wordArr[i].name != "" && wordArr[j].name == "" && i > j) {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
break;
}
}
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 如果这不是类的"复制构造函数",是否可以移动对象?
- 我可以从向量的开头移动对象吗?为什么不呢
- 为什么可以使用已删除的移动构造函数和赋值运算符移动对象?
- 使用参数将仅可移动对象捕获到 lambda
- 初始化不可移动对象数组:为什么这样的代码无法在 GCC 上编译?
- c++ 从成员函数创建新线程并移动对象和整个对象
- 返回unique_ptr或只是移动对象
- 将 OpenGL 实例化图形与移动对象一起使用
- 如何在给定两个点的线上移动对象?
- 使用文件描述符移动对象
- 为什么移动对象不会使其为空?
- 被引用的移动对象
- Maya c++ API,移动对象?
- 为什么传递std ::移动(对象)和此对象的成员函数会导致sigsegv
- 命令模式:如何进行连续操作?(例如,移动对象)
- 返回具有显式构造函数的不可复制的不可移动对象
- 如何在 C++ 中的特定边界内移动对象
- 在阵列中向上移动对象
- DirectX 11 基于旋转移动对象