2014-09-29 154 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