2014-07-25 2 views
0

.dat 파일을 가져오고 명령 프롬프트에 값을 인쇄하여 인쇄하는 프로그램을 만들고 있습니다. 거기에 문제 없습니다. 유일한 것은 한 번만 특정 변수를 인쇄하는 코드를 파악할 수 없다는 것입니다.배열이나 배열이없는 배열에 한 번만 복제본을 인쇄하는 방법

import java.io.*;    
import java.util.Scanner;  

public class program4 
{ 
    public static void main(String [] args) throws IOException 
    { 
     double [] values;    //creating array called values 
     values = new double [40];  //establishing array that has 40 cells 
     int k;       //creating counter integer 

     Scanner InputFile = new Scanner(new FileReader("temp.dat"));  

     k = 0; 

     while (InputFile.hasNextDouble()) //read values from file using ascending while loop 
     { 
      values[k] = InputFile.nextDouble();        
      k++; 
     } 

     for (k = 0 ; k < values.length ; k++) 
      System.out.println(values[k]); 

     InputFile.close(); 
    } 
} 

.dat 파일에 포함 된 중복을 제거하기위한 코드를 초기화하는 가장 좋은 장소는 어디입니까?

+4

호기심 : 왜지도 나 arraylist를 사용하지 않습니까? – csmckelvey

+2

아직 내 수업 (intro level comp sci)에서 다루지 않았으며 교수님은 가르치지 않은 재료를 사용하지 않으려 고합니다 –

+2

인쇄하기 전에 매번 배열을 반복해야합니다. – Ben

답변

0

값이 배열에 한 번 이상 존재하는 경우 확인하는 방법을 만들기

boolean isDuplicate(double x, double[] array, int checkUpTo){ 
    numOfOccurencies = 0; 
    for(int i = 0; i <= checkUpTo; i++) 
     if(x == array[i]) 
      numOfOccurencies++; 
    return(numOfOccurencies > 1)? true : false; 
} 

다음

for (k = 0 ; k < values.length ; k++) 
    if(!isDuplicate(values[k], values, k) 
      System.out.println(values[k]); 

그래서 때마다 당신은 당신이 확인 배열에서 두 번 인쇄하려고 double이 두 번 이상 나타나는 경우 해당 색인으로 이동합니다. 당신이 보장하는 그런 식으로 적어도 한 번 모든 것을 인쇄 할 것입니다. 예를 들어 인덱스 2와 인덱스 4에 값이 표시되면 인덱스 2에서 먼저 확인한 다음 해당 인덱스를 검사하기 때문에 값이 중복되지 않고 인쇄됩니다. 그 다음에는 최대 4 개를 확인하고 두 번째 발생을 찾아 값이 인쇄되지 않도록하십시오.

희망이

편집을하는 데 도움이 : 난 당신이 아니라 당신은 인쇄 할 때 중복을 제거 할 것으로 가정했다. 중복 값을 저장할 해달라고 경우에 당신은 유사한 필요합니다

boolean isDuplicate(double x, double[] array){ 
    for(int i = 0; i < array.length; i++) 
     if array[i] == x 
      return true; 
    return false; 
} 

while (InputFile.hasNextDouble()) //read values from file using ascending while loop 
     { 
      double temp = InputFile.nextDouble(); 
      if(!isDuplicate(temp, values){ 
       values[k] = temp 
       k++; 
      } 


     } 

     for (k = 0 ; k < values.length ; k++) 
      System.out.println(values[k]); 
+0

당신이 그렇게 친절하게 게시 한 부울 (ty btw = D) if array [i] == x x는 어디에 있습니까? 그것은 경계로 언급 된 두 배가 될 것이고 이것은 당신이 while 진술서에있는 두배의 임시 직원일까요? –

+0

예 x는 매개 변수'double x'입니다. Allthough 난 그냥 isDuplicate 메서드를 호출 할 때뿐만 아니라 배열을 전달하지 않는 것으로 나타났습니다. 나는 그 대답을 편집했다.그래서 이것은 올바른'if (! isDuplicate (temp, values)'등 – qbit

+0

마지막 질문 = P를 컴파일하는 동안 "구문 분석 중에 끝에 도달했습니다"라는 오류가 표시됩니다. 이는 다른 곳에서도 반환을 추가해야한다는 것을 의미합니까? ? –

0

프로그램에 대한 간단한 수정은 이미 저장 한 값을 확인하여, 중복 저장하지 귀하의 while 루프를 수정하는 것입니다 :

while (InputFile.hasNextDouble()) //read values from file using ascending while loop 
    { 
     double nextValue = InputFile.nextDouble(); 

     // check to see if next value has already been stored 
     boolean duplicate = false; 
     for (int i=0; i<k; i++) { 
      if (nextValue == values[i]) { 
       duplicate = true; 
       break; 
      } 
     } 

     // only store values if they have not already been read 
     if (!duplicate) { 
      values[k] = nextValue; 
      k++; 
     } 
    } 
또한 인덱스 만까지 배열을 인쇄하려면 인쇄 문을 수정 할 수 있습니다

당신이 쓴하는 값 (k) :

for (int i = 0 ; i < k ; i++) { 
     System.out.println(values[i]); 
    } 
0

한 가지 방법은 배열이 만들어지면 배열을 정렬하고 중복 된 값이 있는지 확인하는 것입니다.

물론 짐작할 수도 있고 항목을 추가 할 때마다 전체 배열을 반복 할 수도 있지만 매우 비효율적입니다. 아래의 솔루션은 처음에는 똑같이 비효율적이지만 최적화 할 수있는 기회가 있습니다.

나는 복사하고 붙여 넣기가 아니라 배우고 싶어한다고 생각하기 때문에 의도적으로 코드를 사용하지 않습니다.

배열 values이 채워지면 (즉, while 루프 이후에) 배열을 정렬하십시오. 이전 실습에서 배열을 정렬하는 방법을 이미 알고 있을지 모르지만 그렇지 않은 경우 bubble sort은 배우기 쉽고 성능이 최악입니다.

간단한 버블 정렬 구현에 대해서는 this answer을 참조하십시오.

function bubbleSort: 
    //values is your array 
    //length is the length of values 
    loop i from 0 to length - 1 
     loop j from i+1 to length - 1 
      if values[i] > values[j] 
       swap values[i] and values[j] 
      end if 
     end loop 
    end loop 
end function 

일단 정렬 된 배열이 있으면 루프를 통해 현재 요소가 이전 요소와 같은지 확인하십시오. 그렇다면 복제본입니다.(당신이 이미 가지고 코드)

  • 채우기 배열
  • 종류의
  • 검색을하고 구축 할 수

한 최적화는 중복 제거 :

function removeDuplicates: 
//values is your array 
//non_duplicate_array is another array with only non duplicate values 
loop from 1 to size-1 //and not from 0, because we are comparing 
         //an element with the previous and 
         //the element at 0 does not have a previous element 
    if values[i] == values[i-1] 
     //duplicate! 
    else 
     add element to non_duplicate_array. 
    end if 
end loop 

그래서 우리는이 정렬 자체가 중복 제거되도록하려면 :

012 여기

loop j from i+1 to length - 1 
    if values[i] > values[j] 
     swap values[i] and values[j] 
    end if 
end loop 

대신 값을 교환, 당신은 다른 배열에 값을 추가 할 수 있습니다, 그래서하는 동안 만이 아닌 중복 수행 :

을 3,516,

이 가장 안쪽의 종류 위의 거품 루프입니다

function bubbleSort: 
    //values is your array 
    //length is the length of values 
    //non_duplicate_array is another array that will eventually have 
    //sorted non duplicate values 
    loop i from 0 to length - 1 
     loop j from i+1 to length - 1 
      if values[i] != values[j] 
       if values[i] > values[j] 
        add values[j] to non_duplicate_array 
       else 
        add values[i] to non_duplicate_array 
       end if 
      end if 
     end loop 
    end loop 
end function 

정렬은 거품 정렬이므로 매우 중첩 된 루프이므로 매우 inefficient입니다. 하지만 이것을 merge sort 또는 빠른 정렬 인 far more efficient으로 바꿀 수 있습니다. 또한 병합 또는 빠른 정렬 알고리즘을 적용하여 중복을 제거 할 수 있습니다.

출력 배열을 정렬하는 데 문제가없는 경우에만 작동합니다. 그렇지 않으면 @ xgeorgekx의 답과 같이 무차별 적으로 강제해야합니다. 또는 Set을 사용하십시오.

편집 :

다음은 모두가 Set으로 필요하다 그냥 당신이 설정에 대한 권장을 많이 볼 이유를 이해할 수 있도록 :

그것 뿐이다
Set valueSet = new HashSet<Double>(); 
    ... 
    ... 
    while (InputFile.hasNextDouble()) 
    { 
     valueSet.add(InputFile.nextDouble()); 
    } 

. 세트에는 중복되지 않는 값만 있습니다. 그렇지만 프로그래밍을 배울 수는 없습니다 :-).