【问题标题】:Issue finding size of dynamic int array that contains a zero问题查找包含零的动态 int 数组的大小
【发布时间】: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 字符永远不会是字符串中的合法字符。如果不决定永远不会成为数据一部分的哨兵值,那么您通常不能使用这种方法,但可以用您使用的类型表示。但是在数组中搜索哨兵以获取长度并不是很有效……通常最好用另一个变量来跟踪它。
  • 我们不允许使用向量。 -- 但是没有什么能阻止你创建一个包含指针、大小成员和必要的成员函数的简单类或结构.这就是你阻止这些限制的方式——创建你自己的“向量”类,甚至是一个最小的类。

标签: c++ arrays dynamic


【解决方案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 种常用方法:

  1. 特殊值,结束标记。这种方法用于 C 风格的字符串,其中 '\0' 用作结尾。对于整数,这种方法不起作用,因为 0 是“正常”值。您可以使用其他一些特殊值,例如 std::numeric_limits&lt;int&gt;::minstd::numeric_limits&lt;int&gt;::max,但这不是很好的方法。
  2. 有另一个变量,它保存数组的当前大小。请注意,这通常与分配的元素数量不同。这可以包装到一个类中。这就是std::vector 的实现方式。
  3. 有另一个变量,指针,它指向最后一个之后的 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();   
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 2018-09-19
      • 1970-01-01
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多