问题查找包含零的动态 int 数组的大小
Posted
技术标签:
【中文标题】问题查找包含零的动态 int 数组的大小【英文标题】:Issue finding size of dynamic int array that contains a zero 【发布时间】:2016-08-03 20:56:09 【问题描述】:我们不允许使用向量。
另一个有问题的菜鸟。我正在尝试查找初始化为 50 大小的动态 int 数组的索引。我们只能使用动态 int 数组。
例如,我只在这个数组中输入 10 个整数:1 9 5 3 8 0 8 2 0 6
数组的其余部分为 NULL。目标是保留输入到此数组中的整数值并将它们放入输出文件中。所以我想要的整数数组的大小是 9。但是当我执行以下操作时:
int index = 0;
while (intArray[index])
index++;
它告诉我索引是 5,因此只有 5 个值被复制到输出文件中。我知道这是因为数组中的 0。如果数组中没有 0,则结果按预期出来。如何绕过这个,以便索引正确反映为 9 并且所有值都被正确复制?感谢您的意见!
【问题讨论】:
我想你一开始构造数组时不能保持大小? 您可以使用自己的哨兵值作为数组末尾的标记,例如-1
或0x8000000
。
"数组的其余部分为 NULL" 这是什么意思?也许展示你如何初始化数组会更容易。
C 字符串可能以 null 结尾...但该约定之所以有效,只是因为它假定 null 字符永远不会是字符串中的合法字符。如果不决定永远不会成为数据一部分的哨兵值,那么您通常不能使用这种方法,但可以用您使用的类型表示。但是在数组中搜索哨兵以获取长度并不是很有效……通常最好用另一个变量来跟踪它。
我们不允许使用向量。 -- 但是没有什么能阻止你创建一个包含指针、大小成员和必要的成员函数的简单类或结构.这就是你阻止这些限制的方式——创建你自己的“向量”类,甚至是一个最小的类。
【参考方案1】:
正如 cmets 中指出的那样,鉴于您不能使用 std::vector
(*sigh*),这里最好的方法是制作自己的最小 dynamic_array
(模仿 std::vector
),它知道自己的大小任何时候。
它的界面可能是这样的:
template<typename _Ty>
class dynamic_array
public:
typedef _Ty value_type;
typedef const _Ty& const_reference;
typedef _Ty& reference;
typedef std::size_t size_type;
//... other necessary typedefs
dynamic_array() : arr(), arr_size(0), allocated_size(0)
dynamic_array(size_type n) : arr_size(n), allocated_size(n) allocate(n);
~dynamic_array() delete arr;
size_type size() const noexcept return arr_size;
const_reference operator[](size_type n) const return arr[n];
reference operator[](size_type n) return arr[n];
void push_back(const value_type& _val)
++arr_size;
// actual implementation of pushing back _val up to you
private:
value_type* arr;
size_type arr_size; // number of elements
size_type allocated_size; // actual number of allocated elements in memory
void allocate(size_type n) arr = new value_type[n];
;
然后通过索引遍历它,您只需这样做:
dynamic_array<int> darr;
// populate darr
for (int i = 0; i < darr.size(); ++i)
// do stuff with each element accessing via: darr[i] as before
编辑 - 如果您可以使用 std::unique_ptr
,请使用它而不是原始指针 value_type* arr
以避免任何潜在的内存管理问题。
【讨论】:
@Hurkyl 如果他/她不能使用std::vector
,那么我怀疑std::unique_ptr
是否也是“允许的”(愚蠢的学校作业),但确实会更好。【参考方案2】:
对于整数值没有 NULL 这样的东西。因此,有 3 种常用方法:
-
特殊值,结束标记。这种方法用于 C 风格的字符串,其中 '\0' 用作结尾。对于整数,这种方法不起作用,因为 0 是“正常”值。您可以使用其他一些特殊值,例如
std::numeric_limits<int>::min
或 std::numeric_limits<int>::max
,但这不是很好的方法。
有另一个变量,它保存数组的当前大小。请注意,这通常与分配的元素数量不同。这可以包装到一个类中。这就是std::vector
的实现方式。
有另一个变量,指针,它指向最后一个之后的 pone 元素。这对于在标准算法中使用可能很有用。
方法 2 和 3 非常接近,可以很容易地转换为另一种。所以我建议使用 start 和 behind_end 迭代器重写你的算法:
auto end = myArray + 5; // 5 elements in array
for( auto it = myArray; it != end; ++it )
std::cout << *it << endl;
此代码可以轻松模板化并与标准容器一起使用。
【讨论】:
【参考方案3】:只有当您确定输入数据不是负数时,您才可以这样做:
#include <iostream>
int main()
int MyArray[50]; // declare your array
// ..
for (int i = 0; i < 50; i++)
MyArray[i] = -1; // fill with negatives
MyArray[0] = 0; // some data
MyArray[1] = 10; // some data
for (int i = 0; i < 50; i++)
if (MyArray[i] >= 0 )
std::cout << MyArray[i];
// write to your file
//..
return 0;
【讨论】:
不幸的是,NULL
被指定为零,所以这并不比 OP 的代码更好。
我认为你是对的,我刚刚测试过。我记得我曾经使用 NULL.. 很好,谢谢。我用不同的方法编辑了我的答案。【参考方案4】:
boost::static_vector 在这里会有所帮助。它本质上是向量和数组之间的交叉:要么是具有固定容量的堆栈分配向量,要么是具有一些工具来跟踪逻辑大小的未初始化数组。
使用示例:
#include "boost/container/static_vector.hpp"
#include <iostream>
namespace cnt = boost::container;
void foo()
cnt::static_vector<int, 50> buf = 1, 9, 5, 3, 8, 0, 8, 2, 0, 6,;
std::cout << buf.size();
int main()
foo();
【讨论】:
以上是关于问题查找包含零的动态 int 数组的大小的主要内容,如果未能解决你的问题,请参考以下文章