2014-09-29 156 views
0

它们添加到端我在data.txt文件等9 3 9 4 5 4 3 7 1 9 6从数组中删除重复的数字,并在C++

阵列我需要找到重复的数字,并从删除它们阵列。

之后,我需要收集他们在数组的末尾。

我写了一个代码,输出是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;} 
+1

我不假设'std :: sort'数组,然后在其上运行'std :: unique'是一个选项。 – WhozCraig 2014-09-29 21:58:01

+3

我期望它的功课,所以一切都必须写成它的C代码,而不是使用适当的C++习惯用法。 – 2014-09-29 22:03:09

+1

您是否需要为您的示例输入获取“{9,3,4,5,7,1,6}”? – 2014-09-29 22:11:18

回答

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; 
} 
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;} 
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; 
} 
0

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

+0

不幸的是,'remove_if'不保证将重复的对象移动到最后。它将对象留在未指定状态下的返回迭代器之后。 – 2014-10-01 00:38:59

+0

'remove_copy_if'可以这样工作,但它必须输出到一个单独的容器 – 2014-10-01 00:41:27