잡탕1 - IT2014. 3. 27. 23:27
 B. n개의 원소를 가지는 1차원 벡터를 i만큼 왼쪽으로 회전시켜라. 예를 들어 n=8, i=3 일 경우 abcdefgh 라는 벡터를 회전시키면 defghabc 가 된다. 간단한 코드로는 n개의 원소를 가지는 임시 벡터를 사용하여 n번의 단계를 통해 해결할 수 있다. 여분의 메모리가 수십 바이트 밖에 안되는 상황에서도 n에 비례하는 시간 내에 벡터를 회전시킬 수 있겠는가?

B는 n개의 원소를 가지는 벡터 x를 i만큼 왼쪽으로 회전 시키는 문제이다. 메모리의 한계를 생각할 때 가능한 방법으로 ①저글링 조작(juggling action)을 사용한 회전과 ②반전을 이용한 회전이 소개되어 있으며 이는 연습문제3 에서 코드로 구현한다

연습문제3 (1) - 저글링 조작(단계별 순차 이동)
/* 생각하는 프로그래밍 칼럼2 B문제1
시작일 : 2009-07-30
완료일 : 2009-07-30

1. 저글링 알고리즘을 이용하여 B문제 풀이
2. vector 는 문자 배열이라고 생각한다
3. 우선 총 8자리에서 3자리 옮기기를 구현한다(n=8, i=3)
4. 사용자 입력 부분은 구현하지 않았다
*/

public class JugglingShift {
public static void main(String[] args) {

String[] vector = {"a","b","c","d","e","f","g","h"};
int i = 3;


int blockCount = (int)Math.ceil((double)vector.length / i); // 블럭 단위 갯수 구하기
String[] block = new String[blockCount]; // 저장할 공간
String temp; // 임시 저장 공간

// 8개 원소를 3블럭으로 분배
for ( int j=0 ; j<block.length ; j++ ) {
for ( int l=0 ; l<vector.length ; l++ ) {

if ( (j*i+l%i) == l ) {
if ( l%i == 0 ) {
block[j] = new String(vector[l]);
} else {
block[j] += vector[l];
}
}
}
}
System.out.println( block[0]+" "+block[1]+" "+block[2] );



// 블럭 저글링
temp = block[0]; // 이동할 블럭을 temp 로
block[0] = block[1]; // 하나씩 당겨 넣는다
block[1] = block[2];
block[2] = temp; // 마지막에 빈 곳에 temp 를

System.out.println( block[0]+" "+block[1]+" "+block[2] );

}
}



연습문제3 (2) - 반전을 이용한 회전
반전 코드를 이용한 회전은 책에도 나와 있지만 '배열의 특정 부분의 원소들을 반전시키는 함수' 가 존재 할 때 가능하다. Java 는 StringBuffer 에 reverse() 메서드를 제공하지만, 간단하게 배열을 역으로 대입하는 방식으로 구현하였다. 물론 배열의 부분 반전도 구현하였다

/* 생각하는 프로그래밍 칼럼2 B문제2
시작일 : 2009-08-02
완료일 : 2009-08-03

1. 반전을 이용한 B문제 풀이
2. vector 는 문자라고 생각한다
3. 우선 총 8자리에서 3자리 옮기기를 구현한다(n=8, i=3)
4. 사용자 입력 부분은 구현하지 않는다
5. reverse() 메서드를 구현한다

*/

public class ReverseShift {
public static void main(String[] args) {

String vector = "abcdefgh";
int i = 3;

System.out.println(vector);

vector = reverse(vector, 0, i-1); // 처음부터 i까지 반전시킨다
System.out.println(vector);

vector = reverse(vector, i, vector.length()-1); // i부터 끝까지 반전시킨다
System.out.println(vector);

vector = reverse(vector, 0, vector.length()-1); // 전체를 반전 시킨다
System.out.println(vector);
}

// vector 문자열을 i 만큼 회전
public static String reverse(String vector, int start, int end) {

String ReverseVector = new String();

ReverseVector += vector.substring(0,start); // 반전하지 않는 앞부분 붙이기

// StringBuffer의 reverse() 를 이용해도 되지만
// 단순하게 배열을 역으로 넣어서 구현하였다
for ( int i=end ; i>=start ; i-- ) {
ReverseVector += String.valueOf(vector.charAt(i));
}

ReverseVector += vector.substring(end+1,vector.length()); // 반전하지 않는 뒷부분 붙이기

return ReverseVector;

}
}


Posted by pearl짓거리전문
잡탕1 - IT2014. 3. 27. 23:27
intro.
프로그래밍은 일종의 창작이다. 주어진 언어의 Spec 을 바탕으로 하고 사용자가 원하는 프로그램을 만들어 내는 것이다. 그런 프로그래밍에 가장 필요한건 무엇일까? 물론 언어의 이해정도가 가장 크겠지만 그런 기본기를 갖춘 프로급 위치에서는 프로그램 설계에 구현되는 논리, 방법, 구성 등이 더욱 중요한 지표가 된다
그 동안 여러 권의 자바 관련 책들을 보아 왔지만 자바 언어의 기초에 관련된 책들만 본 것 같다. 중급으로 가는길.. 그 방법은 앞서 언급한 사고력에 바탕을 둔 창작성이지 않을까?
그런 중 '생각하는 프로그래밍' 이란 책을 알게되었고 프로그래밍에 있어서 기초에서 벗어나는 통찰과 창조의 영역을 공부하고 싶었다. 사실상 필연이라고 봐도 될 듯 하다. 그런 지식에 대한 갈망이 이 책을 찾게 되는 이유일지도 모르겠다




column1은 데이터 정렬에 관한 문제이다
문제는 다음과 같다
입력 : 최대 n개의 양의 정수를 포함하는 파일로, 각 숫자는 n보다 작고, n=10^7 이다
어떤 숫자가 두 번 이상 나오는 것은 치명적 에러이다
정수 이외에 관련된 데이터는 없다

출력 : 입력된 정수를 오름차순으로 정렬한 리스트

제약조건 : 메모리를 많아야 대략 1MB 정도 사용할 수 있고, 디스크 공간은 충분하다
실행시간은 최대 몇 분 정도가 될 수 있고, 10초 정도 안에 작업을 끝낼 수 있으면 충분하다

일반적인 데이터 정렬로는 해당 숫자의 크기(bit)가 크고 처리해야할 데이터 수가 많기 때문에 주어진 메모리로는 40번 작업을 해서 정렬해야 한다. 하지만 책에 소개되어진 bitmap 구조를 이용하여 원하는 정렬을 구현한다. 비트맵 데이터 구조는 원소가 중복되지 않고 원소와 관련된 다른 데이터도 없는 촘촘한 유한 집합 이라는 특성을 이용하여 정렬한 것이다

1. 7자리의 중복되지 않는 양의 정수는 999,999 보다 크고 10,000,000 보다 작은 숫자이다
1,000,000 ~ 9,999,999 까지의 숫자 범위가 주어진 양의 정수의 범위가 된다

2. 10,000,000 자리의 2진수를 만든다고 생각한다면 그 자리에 대한 index 값을 이용하여 해당 자리에 값의 유무만 판단하게 되면(중복되지 않으므로) 일정 범위에서 값의 유무를 판단하고 정렬되어진(숫자의 index 이므로) 2진수를 구할 수 있다. 값이 있는 인덱스를 순서대로 취하면 그 인덱스가 원하는 값이 된다

3. 구현한 Java 코드
- 7자리 중복되지 않는 양의 정수 1,000,000개 만들기 ( Number.java )
// 7자리 양의 정수 랜덤 생성
import java.io.*;
import java.util.*; 

public class Number { 
    public static void main(String[] args) { 

        int k = 1000000; // 만들 숫자 갯수 
        int n = 7; // 몇자리 세팅 

        BitSet bitSet = new BitSet(k); // 정렬을 위한 비트셋 
        bitSet.clear(); // 비트셋 초기화 false 세팅 

        int kn = (int)((Math.pow(10,n)-1)-(Math.pow(10,n-1)-1)); 
        // 자리수에 맞는 범위값, Math.pow : 제곱 구하기 

        try { 
            File file = new File("randomNumber.txt"); 
            BufferedWriter writer = new BufferedWriter(new FileWriter(file)); 

            int l = 0; 
            while ( l < k ) { 
                int m = (int)(Math.random()*kn+(Math.pow(10,n-1))); 
                if ( !bitSet.get(m) ) { 
                    bitSet.set( m, true ); 
                    writer.write(Integer.toString(m)); 
                    writer.newLine(); 
                    l++; 
                } 
            } 

            writer.close(); 
        } catch (IOException ex) { ex.printStackTrace(); } 
    } 
}
randomNumber.txt 라는 텍스트 파일로 7자리 양의 정수 1,000,000 개가 출력된다


- BitSet 클래스를 이용한 1,000,000개 데이터 정렬 ( BitmapSort.java )
import java.io.*;
import java.util.*;

public class BitmapSort {
    public static void main(String[] args) {

        int[] num = new int[1000000]; // 데이터를 넣을 배열 생성

        BitSet bitSet = new BitSet(10000000); // 정렬을 위한 비트셋
        bitSet.clear(); // 비트셋 초기화 false 세팅

        try {
        File myFile = new File("randomNumber.txt");
        BufferedReader reader = new BufferedReader(new FileReader(myFile));
        // 데이터 파일 읽기

        int j=0;
        String line = null;

        while ( (line = reader.readLine()) != null ) {
            StringTokenizer tokenizer = new StringTokenizer(line);
            num[j] = Integer.parseInt (tokenizer.nextToken() );

            bitSet.set(num[j], true);
            // num[j] 의 값이 bitSet 의 인덱스로

            j++;
        }
        reader.close();


        File file = new File("sortedNumber.txt");
        BufferedWriter writer = new BufferedWriter(new FileWriter(file));
        // 파일 출력

        for ( int k=0 ; k<bitSet.length() ; k++ ) {
            if ( bitSet.get(k) ) { // bitSet 값이 true 일때만 파일에 쓰기
                writer.write(Integer.toString(k));
            writer.newLine();
            }
        }
        writer.close();
        } catch (IOException ex) { ex.printStackTrace(); }
    }
}
데이터 파일인 randomNumber.txt 파일을 읽고, 정렬한 데이터를 sortedNumber.txt 로 출력한다


Posted by pearl짓거리전문