Skip to content

Commit c1ad4f1

Browse files
committed
add regexp
1 parent dd92e25 commit c1ad4f1

File tree

8 files changed

+75
-0
lines changed

8 files changed

+75
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
4. [포인터와 동일성](equality/)
1111
5. [파일 읽고 쓰기](file-io/)
1212
6. [비교 연산](compare/)
13+
7. [정규식](regexp/)
1314

1415
## 참고자료
1516
- [Real World OCaml](https://dev.realworldocaml.org/)

regexp/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_build
2+
regex

regexp/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
MAKE=@make
2+
DUNE=@dune
3+
LN=@ln -sf
4+
RM=@rm
5+
BIN=regex
6+
7+
all:
8+
$(DUNE) build src/$(BIN).exe
9+
$(LN) _build/default/src/$(BIN).exe $(BIN)
10+
11+
clean:
12+
$(DUNE) clean
13+
$(RM) -rf $(BIN)

regexp/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# 정규식
2+
3+
## 목표
4+
OCaml 에서 정규식을 효율적으로 다루면서 성능을 최적화 할 수 있어야 한다.
5+
6+
## 구현
7+
`./regex [길이]`를 실행하면 먼저 해당 개수만큼 무작위 정수를 원소를 갖는 `List` 타입의 값을 생성한 후,
8+
각 숫자를 문자열 형태로 바꾼다.
9+
그리고 난 후 각 문자열 중 특정한 정규식(".*9.*9.*")을 만족하는 원소만 골라내는 코드가 구현되어 있다.
10+
11+
OCaml에서 정규식은 `Str.regexp` 함수를 사용하여 만든다.
12+
하지만 많이 반복 생성하는 경우 매우 비효율적이다.
13+
14+
이를 해결하기 위하여, 효율적으로 정규식을 이용하는 `filter_opt` 함수를 작성하라.
15+
이 모듈은 `./regexp -opt [개수]`로 실행할 수 있다.
16+
17+
## 규칙
18+
- 순환문은 재귀 호출로 구현하고 `for` 문을 사용하지 않는다.
19+
- 천만개 원소를 생성하고 검사하는 데 5초를 넘지 않아야 한다. 참고로, Intel(R) Xeon(R) Gold 6226R CPU @ 2.90GHz 에서 아래와 비슷한 성능이 나온다.
20+
```console
21+
$ time ./regexp 10000000
22+
1496356
23+
./regex 10000000 21.35s user 0.41s system 99% cpu 21.759 total
24+
$ time ./regexp -opt 1000000
25+
1496356
26+
./regex 10000000 -opt 3.50s user 0.33s system 99% cpu 3.835 total
27+
```

regexp/dune

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(env
2+
(dev
3+
(flags
4+
(:standard -warn-error -A))))

regexp/dune-project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(lang dune 2.3)

regexp/src/dune

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(executable
2+
(name regex)
3+
(modules regex)
4+
(libraries str))

regexp/src/regex.ml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
let opt = ref false
2+
let input = ref ""
3+
let options = [ ("-opt", Arg.Set opt, "Optimized version") ]
4+
let long_list n = List.init n (fun _ -> Random.int 10000000 |> string_of_int)
5+
6+
let filter_unopt lst =
7+
List.filter
8+
(fun n ->
9+
let regexp = Str.regexp ".*9.*9.*" in
10+
Str.string_match regexp n 0)
11+
lst
12+
13+
let filter_opt lst = failwith "Not implemented"
14+
15+
let main () =
16+
Arg.parse options (fun x -> input := x) "";
17+
let n = int_of_string !input in
18+
let init_list = long_list n in
19+
let filter = if !opt then filter_opt else filter_unopt in
20+
let filter_list = filter init_list in
21+
List.length filter_list |> Printf.printf "%d\n"
22+
23+
let _ = main ()

0 commit comments

Comments
 (0)