【问题标题】:Using a function to remove duplicates from an array in C++使用函数从 C++ 中的数组中删除重复项
【发布时间】:2013-12-28 09:55:16
【问题描述】:

我正在编写一个程序,该程序将用户输入整数到一个数组中,调用一个从该数组中删除重复项的函数,然后打印出修改后的数组。当我运行它时,它允许我将值输入到数组中,但是当我完成输入值时会给我一个“分段错误”错误消息。我做错了什么?

这是我的代码:

#include <iostream>

using namespace std;

void rmDup(int array[], int& size)
{
        for (int i = 0; i < size; i++)
        {
            for (int j = i + 1; j < size; j++)
            {
                if (array[i] == array[j])
                {
                    array[i - 1 ] = array[i];
                    size--;
                }
            }
        }
}
int main()
{
    const int CAPACITY = 100;
    int values[CAPACITY], currentSize = 0, input;

    cout << "Please enter a series of up to 100 integers. Press 'q' to quit. ";

    while (cin >> input)
    {
       if (currentSize < CAPACITY)   
       {
           values[currentSize] = input;
           currentSize++;
       }
    }

    rmDup(values, currentSize);

    for (int k = 0; k < currentSize; k++)
    {
            cout << values[k];
    }

    return 0;
}

谢谢。

【问题讨论】:

  • 对于c++ 考虑使用std::vector&lt;int&gt; 而不是int array[]
  • 为什么不使用标准库? using namespace std; sort(begin(values), end(values)); size = unique(begin(values), end(values)) - begin(values);
  • 我不知道这些命令(排序、结束、唯一),但我一定会熟悉它们。
  • 考虑边界线情况(处理数组时的一般技术)。当 i = size - 1 时, j 将变为 size 。它意味着 array[j] 将是 array[size] 。这意味着崩溃:)

标签: c++ arrays function segmentation-fault


【解决方案1】:

我什至无法创建重复项:

int main()
{
    const int CAPACITY = 100;

    cout << "Please enter a series of up to 100 integers. Press 'q' to quit. ";

    std::set<int> myInts;
    int input;
    while (std::cin >> input && input != 'q' && myInts.size() <= CAPACITY) //note: 113 stops the loop, too!
       myInts.insert(input);

    std::cout << "Count: " << myInts.size();
}

帮自己一个忙,不要使用原始数组。查看 STL。

【讨论】:

  • 我最初并没有意识到我可能会不小心创建重复的数组。感谢您的提示。
  • 您创建的不是重复的数组,而是数组中的重复值。 std::set“防止”。
【解决方案2】:
for (int i = 0; i < size; i++)
{
    for (int j = i + 1; j < size; j++)
    {
        if (array[i] == array[j])
        {
            array[i - 1 ] = array[i]; /* WRONG! array[-1] = something */
            size--;
        }
    }
}

如果array[0]array[1] 相等,则array[0-1] = array[0],即array[-1] = array[0]。你不应该访问array[-1]

【讨论】:

  • 这些 cmets 让我走上了正确的道路。我对这个社区的反应速度感到惊讶。谢谢。
【解决方案3】:
#include<iostream>
#include<stdio.h>
using namespace std;

int arr[10];
int n;

void RemoveDuplicates(int arr[]);
void Print(int arr[]);


 int main()
{

cout<<"enter size of an array"<<endl;
cin>>n;
 cout<<"enter array elements:-"<<endl;
for(int i=0;i<n ;i++)
{
    cin>>arr[i];
}
RemoveDuplicates(arr);
Print(arr);
}

 void RemoveDuplicates(int arr[])
{
   for(int i=0;i<n;i++)
{
    for(int j=i+1;j<n;)
    {
        if(arr[i]==arr[j])
        {
            for(int k=j;k<n;k++)
            {
                arr[k]=arr[k+1];

            }
            n--;
        }
        else
            j++;
    }
}
}

void Print(int arr[])
{
   for(int i=0;i<n;i++)
   {
      cout<<arr[i]<<"  ";
    }
 }

【讨论】:

    【解决方案4】:
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    
    using namespace std;
    int main()
    {
        vector<int> vec = {1,1,2,3,3,4,4,5,6,6};
        auto it = vec.begin();
    
        while(it != vec.end())
        {
            it = adjacent_find(vec.begin(),vec.end());
            if(it != vec.end())
                vec.erase(it);
                continue;
        }
    
        for_each(vec.begin(),vec.end(),[](const int elem){cout << elem;});
        return 0;
    }
    

    此代码使用 C++11 编译。

    【讨论】:

    • 我认为使用vec.erase(unique(begin(vec), end(vec)), end(vec)); 会更快,而且也摆脱了循环。
    • for_each(vec.begin(),vec.end(),[](const int elem){cout &lt;&lt; elem;}); 或者基于范围:for(auto const&amp; e : vec) std::cout&lt;&lt;e&lt;&lt;", ";
    • 当您使用vec.erase(it) 时,会使it 无效。我不确定将无效迭代器与结束迭代器进行比较是否安全(在下一次循环迭代中)。
    • 使用std::vector 进行擦除代价高昂,因为在每次调用 erase() 后必须重新分配所有后续元素。在这种情况下,应该首选具有恒定擦除时间的std::list
    • 我还没有开始使用向量,但会研究它们。感谢您的帮助。
    猜你喜欢
    • 2012-03-25
    • 2019-03-15
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2010-09-05
    相关资源
    最近更新 更多