问题查找包含零的动态 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 并且所有值都被正确复制?感谢您的意见!

【问题讨论】:

我想你一开始构造数组时不能保持大小? 您可以使用自己的哨兵值作为数组末尾的标记,例如-10x8000000 "数组的其余部分为 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&lt;int&gt;::minstd::numeric_limits&lt;int&gt;::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 数组的大小的主要内容,如果未能解决你的问题,请参考以下文章

在 NumPy 数组中查找等于零的元素的索引

如何在 C 中找到动态分配数组的大小?

C ++中动态大小的二维数组中的用户输入

如何获取动态分配的二维数组的大小

查找指针指向的数组的大小[重复]

在 N×N 二进制矩阵中查找仅包含零的最大矩形