2014-10-28 2 views
0

사용자의 입력 인 연결된 목록에서 어떤 값과 중복 된 값을 식별할지 알고 싶습니다. 그리고 이것은 내가 그것을 위해 쓴 코드 :연결된 목록의 중복 값 식별 C++

int count; 
int compare, compare2; 

    for (p = first; p != NULL; p = p->next){ 
     compare = p->num; 
     for (j = first; j != NULL; j = j->next){ 
      if (compare == j->num){ 
       compare2 = j->num; 
       count++; 
      } 
     } 
     if (count > 1){ 
      cout << "There are at least 2 identical values of: " << compare2 << " that repeat for: " << count << "times" << endl; 
     } 
    } 

는 기본적으로 그것의 아이디어는 내가 처음 루프에서 첫 번째 요소를 가지고 두 번째 루프의 모든 요소를 ​​비교하고 경우가있는 경우 계산이었다 그 (것)들의 유사 하, 결과를 인쇄하십시오 - 그 후에 다음 성분을 가지고 간다.

그러나 출력은 모든 요소이며 정확하게 계산되지 않습니다. 나는 그것을 조정하는 방법에 그냥 길을 잃었 어.

두 개의 루프에서 동일한 p 변수를 사용했지만 루프를 반복하려는 동일한 목록이므로 시도했지만 입력이 끝나자 마자 .exe가 실패했습니다.

중복 값을 삭제하는 기능이있는 곳에서 몇 가지 예를 보았지만 비교 부분은 while 루프와 함께 실행됩니다. 궁금한 점은 무엇입니까?

+2

디버거를 사용하여 코드를 한 줄씩 단계별로 실행하여 실제로 문제가 발생하는 경우 그것? –

+0

O (n^2) 루프를 작성하는 대신에'std :: map '를 사용하면 쉽게 할 수 있습니다. – PaulMcKenzie

+0

'count'를 0으로 초기화하지 않았습니다. – PaulMcKenzie

답변

0

pj이 모두 전체 목록에서 반복되므로 논리에 결함이 있습니다. p == j 일 때 값은 일치하도록 바인딩됩니다.

변경 또한

 if (p != j && compare == j->num){ 
      compare2 = j->num; 
      count++; 
     } 

에 블록

 if (compare == j->num){ 
      compare2 = j->num; 
      count++; 
     } 

, 당신은 compare와 동일합니다 compare2 때문에 라인

  compare2 = j->num; 

필요하지 않습니다.

내부 for 루프를 조금 변경하여 테스트 수를 줄일 수 있습니다. 그런 다음 p != j 비트가 필요하지 않습니다.

for (j = p->next; j != NULL; j = j->next){ 
     if (compare == j->num){ 
      count++; 
     } 
    } 
+0

고마워요! 귀하의 충고는 실제로 문제의 일부를 수정하지만 출력은 여전히 ​​글리치가 있습니다. 루프가있는 모든 시간에 대해 반복되는 값을 출력하거나 (2 차 수정) 적어도 한 번 반복되는 모든 값을 출력합니다. – TangoJuliet

0

문제는 당신이 (compare)와 비교하는 요소를 제외하지 않는다는 것입니다. 그래서 모든 요소에 대해 적어도 하나의 중복을 발견했습니다 - 그 자체! 내부 루프의 요소 다음에 현재 (p) 뒤에 오는 요소를 비교해보십시오.

+0

이를 수정하기 위해 두 번째 if 문을 적용했습니다. like - count는 자신을 검사 할 때 적어도 어쨌든 1로 묶여 있지만, 값이 클 경우 값은 목록의 뒷부분에서 반복됩니다. 그러나 의도 한대로 작동하지 않았습니다. – TangoJuliet

+0

@Elsa'compare = p-> num;의 바로 앞에'count = 0;'를 추가하십시오. – NikolayKondratyev

+0

Omg, 예! 이제 작동합니다! 당신의 충고와 @ R-Sahu로 마침내 완벽하게 작동합니다! 고맙습니다!! 정말 미안 해요, 아직 upvote 수 없습니다, 당신은 모두 대단히 도움 :) – TangoJuliet

1

귀하의 O (N * N) 방법 :

// Pick an element 
for (p = first; p != NULL && p->next !=NULL ; p = p->next) 
{ // Compare it with remaining elements 
    for (j = p->next ; j != NULL; j = j->next) 
    { 
     if (p->num == j->num) 
     {   
      count++; 
     } 
    if(cout > 1) 
    { 
     std::cout << p->num << " occurs "<< count << times << '\n' ; 
    } 
} 

그것의 더 나은이 문제를 해결하기는 HashMap을 사용하는이 O (N)이다 N 여분의 공간

시간
std::unordered_map<int, int> m ; 
for(p = first; p != NULL ; p = p->next) 
{ 
    m[ p->num ]++; 
} 
for (const auto &pair : m) 
{ 
    if(pair.second > 1) 
     std::cout << pair.first << ": " << pair.second << '\n'; 
}