从数组中删除重复数字并将其添加到c ++末尾

时间:2014-09-29 21:49:43

标签: c++ arrays

我在data.txt档案中有一个数组,如9 3 9 4 5 4 3 7 1 9 6

我需要找到重复的数字并从数组中删除它们。

之后我需要在数组末尾收集它们。

我写了一个代码,输出是9 3 4 5 7 1 6 9 3 4 9,但是我需要将重复的数字放在数组中,按照它们在原始数组中出现的顺序。

所以我需要将{ 9, 3, 4, 5, 7, 1, 6, 9, 4, 3, 9 }作为输出。

如何使用代码实现目标?

#include <iostream>
#include <fstream>
using namespace std;
#define SZ 11
int main(){
    ifstream fs("data.txt");
    if (!fs)
        return 0;
    int a[SZ];
    for (int i = 0; i < SZ; ++i)
        fs >> a[i];
    for (int k=0; k<SZ; k++) {
        for (int j=k+1; j< SZ ; j++) {
            if (a[j]==a[k]) {
                for (int l=j; l<SZ-1; l++) {
                    a[l]=a[l+1];
                }
                a[10]=a[k];
            }
        }
    }
    for (int i = 0; i < SZ; ++i)
        cout << a[i];
    return 1;}

4 个答案:

答案 0 :(得分:0)

如果您想保留订单,则必须将每个数字与之前的数字进行比较,而不是将其与下一个数字进行比较。你的计划成为:

#include <iostream>
#include <iostream>
#include <fstream>
using namespace std;
#define SZ 11
int main(){
ifstream fs("data.txt");
    if (!fs)
        return 0;
    int a[SZ];
    for (int i = 0; i < SZ; ++i)
        fs >> a[i];
    // kk limits the number of iteration, k points to the number to test
    for (int k=0, kk=0; kk<SZ; kk++, k++) {
        for (int j=0; j< k ; j++) {
            if (a[j]==a[k]) {
                for (int l=k; l<SZ-1; l++) {
                    a[l]=a[l+1];
                }
                a[SZ - 1]=a[j];
                // a[k] is a new number and must be controlled at next iteration
                k -= 1;
                break;
            }
        }
    }
    for (int i = 0; i < SZ; ++i)
        cout << a[i];
    return 1;}

答案 1 :(得分:0)

这是一个策略。

保持并行数组中条目是否重复的概念。

首先打印不重复的数字。

然后打印重复的数字。

#include <iostream>
#include <fstream>
using namespace std;
#define SZ 11
int main()
{
   ifstream fs("data.txt");
   if (!fs)
      return 0;
   int a[SZ];
   int isDuplicate[SZ];
   for (int i = 0; i < SZ; ++i)
   {
      fs >> a[i];
      isDuplicate[i] = false;
   }

   for (int k=0; k<SZ; k++) {
      for (int j=k+1; j< SZ ; j++) {
         if (a[j]==a[k])
         {
            isDuplicate[j] = true;
         }
      }
   }

   // Print the non-duplicates
   for (int i = 0; i < SZ; ++i)
   {
      if ( !isDuplicate[i] )
         cout << a[i] << " ";
   }

   // Print the duplicates
   for (int i = 0; i < SZ; ++i)
   {
      if ( isDuplicate[i] )
         cout << a[i] << " ";
   }
   cout << endl;

   // Not sure why you have 1 as the return value.
   // It should be 0 for successful completion.
   return 0;
}

答案 2 :(得分:0)

OP(@kuvvetkolu)原始示例具有O(SZ ^ 3)复杂度,这是残酷的。 @ RSahu的解决方案是O(SZ ^ 2),一个改进(和正确),但这不应该要求O(N ^ 2)......

这是一个只产生空间开销的版本(假设O(1)哈希表查找)。您可以使用unordered_set(哈希表)来跟踪您是否已经看到了特定的数字,将其放在适当的向量中,然后在最后合并向量。

#include <iostream>
#include <fstream>
#include <unordered_set>
#include <vector>

int main() {
    std::ifstream fs("data.txt");
    if (!fs)
        throw std::runtime_error("File not found!");

    std::vector<int> a;
    std::vector<int> dups;
    std::unordered_set<int> seen;

    int d;
    while (fs) {
        fs >> d;
        if (seen.find(d) == seen.end())
        {
            a.push_back(d);
            seen.insert(d);
        }
        else
        {
            dups.push_back(d);
        }
    }

    a.insert(a.end(), dups.begin(), dups.end());

    for (auto n : a)
        std::cout << n << " ";

    return 0;
}

答案 3 :(得分:0)

我倾向于试用一个使用std :: remove_if的解决方案,并且有一个重复的一元谓词。这应该保留你的重复元素的顺序。