0

问题是,我有一个由 10 个整数组成的数组,其中有一些重复项。任务是将此数组复制到另一个相同大小但没有重复值的数组。即从array1中读取一个元素,将其与array2中的所有元素进行比较,如果已经在array2中,则跳过它或打印它已经在array2中,转到array1的第二个元素,并重复该过程。现在,我已经尝试过了,但不知道问题出在哪里:

#include <iostream>
using namespace std;

int main()
{
    int temp;

    int array1[] = {10,2,5,4,10,5,6,9,8,10};
    int array2[11] = {0};

    for(int i = 1; i <= 10; i++)
    {
            temp = array1[i-1];

            for(int j = 1; j <= 10; j++)
            {
                    if(temp == array2[j])
                    {
                            cout << "Duplicate " << temp << endl;
                            i++;
                            break;
                    }
            }

            array2[i] = array1[i-1];
    }

    for(int k = 1; k <= 10; k++)
            cout << array2[k] << "  " << endl;
system("pause");
}
4

7 回答 7

3

array1有 10 个元素,array2有 11 个元素,所以没有满足要求。for据推测,有 11 个元素是在循环中使用不正确索引值的一种解决方法;索引应该从 0 到 9,而不是从 1 到 10。

当您将一个元素添加到第二个数组时,您应该只根据已添加的元素检查它的值,而不是检查整个数组中的值。

最后,规格不足。消除重复项后,您的元素将少于 10 个;array2有 10 个元素;额外的元素应该有什么值?

于 2013-07-10T14:37:03.187 回答
1

std::unique_copy 是你的朋友: http ://en.cppreference.com/w/cpp/algorithm/unique_copy

记得先对源数组进行排序

于 2013-07-10T14:36:31.110 回答
0

在 C++ 中,break立即结束一个循环结构,并在其后立即开始执行。因此,无论内部循环是否找到重复项,该行array2[i] = array1[i-1];都会执行。for一种解决方案是设置一个变量来指示该值是重复的:

 int main() {
     int temp;
     bool isDuplicate; //added this line

     int array1[] = {10,2,5,4,10,5,6,9,8,10};
     int array2[11] = {0};

     for(int i = 1; i <= 10; i++)
     {
             temp = array1[i-1];
             isDuplicate=false;//added this line
             for(int j = 1; j <= 10; j++)
             {
                     if(temp == array2[j])
                     {
                             cout << "Duplicate " << temp << endl;
                             i++;
                             isDuplicate=true; //added this line
                             break;
                     }
             }
             if(!isDuplicate) //added this line
             array2[i] = array1[i-1];
     }

     for(int k = 1; k <= 10; k++)
             cout << array2[k] << "  " << endl; system("pause"); }

或者(尽管许多程序员不同意这种做法)您可以使用goto语句而不是break语句:

int main()
{
    int temp;

    int array1[] = {10,2,5,4,10,5,6,9,8,10};
    int array2[11] = {0};

    for(int i = 1; i <= 10; i++)
    {
            temp = array1[i-1];

            for(int j = 1; j <= 10; j++)
            {
                    if(temp == array2[j])
                    {
                            cout << "Duplicate " << temp << endl;
                            i++;
                            goto duplicate; //added this line
                    }
            }

            array2[i] = array1[i-1];
            //added next line
            duplicate:
    }

    for(int k = 1; k <= 10; k++)
            cout << array2[k] << "  " << endl;
system("pause");
}
于 2013-07-10T14:40:32.407 回答
0

你有三种方法:

  • 逐一比较每个元素(O(N^2)性能)
  • 对您的参考数组进行排序并使用二进制搜索来确定元素是否存在(O(N*lnN)性能)
  • 创建查找哈希(O(1)性能)
于 2013-07-10T14:36:17.423 回答
0

您可以使用 std::set 来确保您的唯一性。

http://en.cppreference.com/w/cpp/container/set

于 2013-07-10T14:42:38.477 回答
0

我可以在您的代码中看到问题的两个主要来源:1)该break语句实际上并没有解决区分发现重复的情况以及何时应将 array1 中的元素添加到 array2 的问题。2)没有计数器可以存储到目前为止插入到array2中的元素数量,这样它们就不能被复制到彼此相邻的array2中。修复两者的代码是:

#include <iostream>
using namespace std;

int main()
{

  int array1[] = {10,2,5,4,10,5,6,9,8,10};
  int array2[10];

  int array2_elements_inserted = 0; 

  for(int i = 0; i < 10; i++)
    {
      int temp = array1[i];

      bool isDuplicate = false; 
      for(int j = 0; j < array2_elements_inserted; j++)
        {
          if(temp == array2[j])
            {
              cout << "Duplicate " << temp << endl;
              isDuplicate = true; 
              break;
            }
        }

      if (!isDuplicate)
        {
          array2[array2_elements_inserted] = temp;
          ++array2_elements_inserted; 
        }
    }

    for(int k = 0; k < array2_elements_inserted; k++)
        cout << array2[k] << "  " << endl;
  //  system("pause");
}

输出:

10  
2  
5  
4  
6  
9  
8  
于 2013-07-10T14:42:45.577 回答
-1

首先,使用动态容器。尤其是看看标准库提供的那些,例如std::vector. 其次,您应该使用集合数据结构来跟踪您之前看到的元素,例如,std::set.

然后它只是对输入数组的迭代并将新元素附加到输出数组。

这是一个例子:

#include <vector>
#include <set>
#include <iostream>

int main() {
    // define and print input data
    std::vector<int> v1 = {10,2,5,4,10,5,6,9,8,10};
    for (int i : v1) 
        std::cout << i << " ";
    std::cout << "\n";
    // this will soon contain the output data
    std::vector<int> v2;
    // a set to keep track of the already seen elements 
    std::set<int> set;
    // iterate the input array using range-based for loop
    for (int i : v1) {
        // check for duplicates
        if (set.find(i) == set.end()) {
            // first occurrence, insert to set, append to output data
            set.insert(i);
            v2.push_back(i);
        }
        else {
            // seen before, do nothing
        }
    }
    // print output data
    for (int i : v2) 
        std::cout << i << " ";
    std::cout << "\n";    
}

输出:

$ g++ test.cc -std=c++11 && ./a.out
10 2 5 4 10 5 6 9 8 10 
10 2 5 4 6 9 8 

以供参考:

于 2013-07-10T14:54:41.757 回答