【问题标题】:Deleting element from an array in c++从 C++ 中的数组中删除元素
【发布时间】:2016-04-06 14:57:31
【问题描述】:

我已阅读其他帖子,但他们没有完全回答我的问题。 我正在学习从书中的数组中删除元素并尝试应用该代码。 据我所知,我传递数组错误或者它是按地址发送整数(不知道这背后的含义)。

#include <iostream>
#include <cstdlib>
using namespace std;

void delete_element(double x[], int& n, int k);

int main()
{
    // example of a function
    int mass[10]={1,2,3,45,12,87,100,101,999,999};
    int len = 10;

    for(int i=0;i<10;i++)
    {
        cout<<mass[i]<<" ";
    };

    delete_element(mass[10],10&,4);

    for(int i=0;i<10;i++)
        cout<<mass[i]<<" ";

    return 0;
}

void delete_element(double x[], int& n, int k)
{
    if(k<1 || k>n)
    {
        cout<<"Wrong index of k "<<k<<endl;
        exit(1); // end program
    }

    for(int i = k-1;i<n-1;i++)
        x[i]=x[i+1];

    n--;
} 

【问题讨论】:

  • 请注意intdouble 不一样。此代码不会编译。此外,对于 C++ 代码来说,这真的不是很典型。
  • delete_element(mass, len, ?);通常你应该发送变量而不是数字
  • 你不能从数组中“删除”一个元素,你只能移动它们的值。至于delete_element(mass[10],10&amp;,4); 行:mass[10] 访问 10 大小数组中的第 11 个元素,这将导致未定义的行为(充其量是段错误),10&amp; 是表达式的一半,不会编译
  • x - 是主数组 n - 数组长度 k- 要删除的元素(实际上删除,因为我从其他帖子中了解到,实际上不可能完全删除元素)
  • @Peter -- k 是从零开始的吗?如果是这样,测试是错误的。如果不是,这与 C++ 通常引用数组元素的方式背道而驰。在 C++ 中,我们从 0 开始,而不是 1。

标签: c++


【解决方案1】:

您的代码中有几个错误。我强调了问题中的一些主要问题1-3

  1. 您调用exit,它不提供对任何对象的适当清理,因为它继承自C。这在这个程序中不是什么大问题,但它合二为一。

    处理此类错误的一种正确方法是抛出异常
    cout<<"Wrong index of k "<< k <<endl; exit(1);
    应该是这样的:
    throw std::runtime_error("invalid index");
    并且应该在其他地方处理。
  2. 您将函数参数声明为采用int&amp;,但您这样调用函数:delete_element(mass[10],10&amp;,4); 10&amp; 正在传递10地址。只需传递值 10 即可。
  3. 您正在从原始 C 数组中“删除”一个函数。这本质上是没有意义的。您实际上无法删除此类数组的一部分。它是在堆栈上创建的恒定编译时间大小。函数本身不进行任何删除,尝试将函数命名为更面向任务的名称。
  4. 您正在使用 C 阵列。除非你有充分的理由,否则不要这样做。使用std::arraystd::vector。这些容器知道它们自己的大小,vector 管理它自己的内存,并且可以轻松地调整大小。借助容器,您还可以访问 STL 的全部范围,因为它们支持迭代器。

我建议你重写代码,实现某种类型的 STL 容器

【讨论】:

    【解决方案2】:

    第 15 行:语法错误 你不能传递一个数字& 如果要通过引用传递,则需要先创建一个变量,如:

    您的 delete_element 函数签名与您声明的数组冲突。使用 double 数组或 int 数组并确保签名匹配。

    delete_element(mass, len , 4);
    

    当你写一个不带括号的数组名时,它与 &mass[0] 相同 IE。指向第一个元素的指针。

    完整的更改应该是:

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    
    void delete_element(int x[], int& n, int k);
    
    int main(){
        // example of a function
        int mass[10] = { 1, 2, 3, 45, 12, 87, 100, 101, 999, 999 };
        int len = 10;
    
        for (int i = 0; i<10; i++){ cout << mass[i] << " "; };
        cout << endl;
    
        delete_element(mass, len , 4);
    
        for (int i = 0; i<10; i++)cout << mass[i] << " ";
        cout << endl;
    
        cin.ignore();
        return 0;
    }
    
    void delete_element(int x[], int& n, int k){
        if (k<1 || k>n){
            cout << "Wrong index of k " << k << endl;
            exit(1); // end program
        }
    
        for (int i = k - 1; i<n - 1; i++)
            x[i] = x[i + 1];
        n--;
    }
    

    【讨论】:

      【解决方案3】:

      您的程序中有几个错误。 除了一些语法问题之外,您还试图将 int 数组传递给需要 double 数组的函数。

      您不能传递 int 文字的左值引用。您想要的是传递对 int 数组长度的引用。另见http://en.cppreference.com/w/cpp/language/reference

      这是您的程序的更新版本。

      #include <iostream>
      #include <cstdlib>
      
      using namespace std;
      
      void delete_element(int x[], int& n, int k);
      
      int main() {
        // example of a function
        int mass[10] = { 1,2,3,45,12,87,100,101,999,999 };
        int len = 10;
      
        for (int i = 0;i < len;i++)  
          cout << mass[i] << " "; ;
        cout << endl;
      
        delete_element(mass, len, 4);
      
        for (int i = 0;i < len;i++) // len is 9 now
          cout << mass[i] << " ";
        cout << endl;
      
        return 0;
      }
      
      void delete_element(int x[], int& n, int k) {
        if (k<1 || k>n) {
          cout << "Wrong index of k " << k << endl;
          exit(1); // end program
        }
      
        for (int i = k - 1;i<n - 1;i++)
          x[i] = x[i + 1];
        n--;
      }
      

      【讨论】:

        【解决方案4】:

        虽然它没有直接回答您的问题,但我想向您展示如何使用 C++ 以更简单的方式解决您的问题。

        #include <vector>
        #include <iostream>
        
        void delete_element(std::vector<int>& v, const unsigned i)
        {
            if (i < v.size())
                v.erase(v.begin() + i);
            else
                std::cout << "Index " << i << " out of bounds" << std::endl;
        }
        
        int main()
        {
            std::vector<int> v = {1, 2, 3, 4, 5, 6, 7};
            delete_element(v, 4);
        
            for (int i : v)
                std::cout << i << std::endl;
        
            return 0;
        }
        

        【讨论】:

        • @BeyelerStudios。这当然是一个很好的论点,但我非常支持让新程序员立即意识到他们正在使用 C++ 而不是 C 的事实。但是你是对的,我已经编辑了我的答案以满足你的评论。跨度>
        【解决方案5】:

        您不能从数组中删除元素,因为数组的大小是固定的。鉴于此,只需调用适当的算法函数std::copy 即可完成delete_element 的实现。

        此外,我强烈建议您让元素删除从 0 开始的值,而不是从 1 开始。

        另一个说明:don't call exit() in the middle of a function call

        #include <algorithm>
        //...
        void delete_element(int x[], int& n, int k) 
        {
            if (k < 0 || k > n-1 )
            {
               cout << "Wrong index of k " << k << endl;
               return;
            }
        
            std::copy(x + k + 1, x + n, x + k);
            n--;
        }
        

        Live Example removing first element

        std::copy 调用将元素从源范围(由k 之后的元素和最后一项(由n 表示)定义)移动到目标范围(k 处的元素)。由于目标不在源范围内,std::copy 调用可以正常工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-31
          • 1970-01-01
          相关资源
          最近更新 更多