2014-11-10 5 views
2

여러 파일에 걸쳐 단어 목록을 일부 나열 했으므로이 파일들을 모두 하나의 파일로 병합하는 빠른 방법이 필요합니다. 병합 할 때 중복을 제거하여 최종 목록에 단일 단어의 여러 인스턴스가 포함되지 않도록하고 싶습니다.반복 필터 목록 - 중복 제거 목록

예 :

텍스트 파일 list_a.txt 말한다 다음

합병
foo 
bar 
peach 
car 

, 출력 파일 말을해야합니다

apple 
pear 
peach 

텍스트 파일 list_b.txt은 다음 말한다 :

apple 
pear 
peach 
foo 
bar 
car 

list_a.txtlist_b.txt에는 peach라는 단어가 포함되어 있지만 출력 파일에는 한 번만 나타납니다.

여기에 사용 된 코드입니다 :

int main() 
{ 
    string myList = ""; 
    string myFiles[] = {"list_a.txt", "list_b.txt"}; 
    string line; 
    int iterationsSinceSleep = 0; 
    size_t length = sizeof(myFiles)/sizeof(myFiles[0]); 
    for(unsigned int i = 0; i < length; i++){ 
     cout<<"Starting " << myFiles[i] << endl; 
     ifstream myfile((string("C:/words/").append(myFiles[i])).c_str()); 
     if (myfile.is_open()) 
     { 
      while (getline (myfile,line)){ 
       string trimmedLine = trim(line); 
       if(myList.find(trimmedLine) == string::npos){ 
        myList.append(trimmedLine + '\n'); 
       } 

       iterationsSinceSleep++; 
       iterationsSinceSleep %= 10000; 
       // Save the CPU! 
       if(iterationsSinceSleep == 0) Sleep(10); 

      } 
      myfile.close(); 
     }else{ 
      cout << "Could not open & process " << myFiles[i] << endl; 
     } 
     Sleep(75); // Save the CPU! 
     iterationsSinceSleep = 0; 
    } 

    // write to the file 
    ofstream myfile ("C:/words/merged/final.txt"); 
    if (myfile.is_open()) 
    { 
     cout<<"Writing filtered list"<<endl; 
     myfile << myList; 
     myfile.flush(); 
     myfile.close(); 
    }else{ 
     cout<<"Could not save filtered list."<<endl; 
    } 



    return 0; 
} 

이 작은 목록/파일에 대한 잘 작동하지만 내 목록 중 하나는 몇 만 라인이있다.

수백만 줄이 포함 된 여러 파일을 처리해야하는 경우에도이 코드를 제대로 실행하는 방법이 필요합니다.

내 개선을위한 첫 번째 아이디어는 고유 한 줄을 저장하기 위해 문자열 대신 배열이나 벡터를 사용하는 것입니다. 그러나이 두 가지 방법 모두 장점과 단점이 있습니다. 삽입

  • Reallocing : 배열을 사용

단점 액세스

  • 빠른 비교 검사 (I) 생각
  • 빠른 소자 : 배열을 사용

    프로 새 문자열이 느릴 수 있습니다.

  • p

    • 동적으로 기능
    검색에
  • 내장 요소를 추가 : rogram 배열의 길이의 트랙 (안 큰 문제지만, 배) 벡터를 사용

장점을 유지해야

벡터 사용의 단점 :

  • 엘레멘트 삽입하기 벡터에 ents가 느리다 (그래서 나는 읽었다)
  • 나는 벡터에 더 많은 오버 헤드가 있다고 생각한다.

누구든지이 코드를 개선하고 더 효율적으로 작성할 수 있습니까? 속도가 주요 관심사이지만 메모리 소비도 고려해야합니다.

미리 감사드립니다.

+0

배열을 사용하지 마십시오. 그리고 저장한다면 dups를 허용하지 않는 데이터 구조를 사용하십시오, 2 마리의 새들. – ChiefTwoPencils

+0

안녕하세요, @ChiefTwoPencils, 당신은 더 나은 대안에 대한 어떤 추론과 아마도 의견을 제시 할 수 있습니까? – SpencerD

+0

당신이 그 논리를 은폐했다고 생각합니다. 배열의 크기를 조정하면 노력/비용이 들지 않습니다. – ChiefTwoPencils

답변

1

std::set을 사용하십시오. 세트가 중복 항목을 허용하지 않습니다. 다음과 같이 시도하십시오 :

std::set<std::string> mySet; 
... 
mySet.insert(trimmedString); 
... 
for (auto &&str : mySet) 
    myFile << str; 

참고 : 여기에 입력 했으므로 오타가있을 수 있습니다.

참고 사항 : 출력을 정렬하므로 원하는지 확실하지 않습니다.

+0

정렬은 빠르고 효율적이기 때문에 정렬이 좋습니다. 나는 그 생각을 좋아한다. 확실히'std :: set'을 살펴볼 것입니다. – SpencerD

+1

조회는 O (로그 n)이며 모든 오브젝트가 별도로 할당되기 때문에 삽입 속도가 느릴 수 있지만 일반적으로 배열이나 벡터 정렬을 유지하는 것보다 훨씬 빠릅니다. 또한 코드를 더 간단하게 만든다. (예를 들어, 이미 세트에 있는지 확인하지 않고'insert'를 호출 할 수있다.) –

+1

주문에 신경 쓰지 않는다면, 'unordered_set'이 더 빠를 수도 있습니다. –