C언어 질문

익명 사용자의 이미지

어떤 데이터에서 찾고자하는 자료를 찾을경우 FOUND 라는 출력을하고
없을경우 NOT FOUND 라는 출력을 한번만 나타나게 하려고 합니다

예시로

#include <iostream>
using namespace std;
 
void main() {
	int test[10];
	for (int i = 0; i != 10; ++i) {
		test[i] = i;
	}
 
	for (int i = 0; i != 10; ++i) {
		if (test[i] == 7) {
			cout << "FOUND" << endl;
		}
		else {
			cout << "NOT FOUND" << endl;
		}
	}
}

이 경우 "NOT FOUND"가 7번 출력되고 "FOUND"가 1번 출력됩니다

#include <iostream>
using namespace std;
 
void main() {
	int test[10];
	for (int i = 0; i != 10; ++i) {
		test[i] = i;
	}
 
	int count = 0;
	for (int i = 0; i != 10; ++i) {
		if (test[i] == 7) {
			count++;
		}
	}
	if (count != 0) {
		cout << "FOUND" << endl;
	}
	else {
		cout << "NOT FOUND" << endl;
	}
}

이 경우 "FOUND"가 한번만 출력되고 'test[i] == 11' 가 될 경우 "NOT FOUND"가 한번만 출력됩니다
두번째 코드의 출력이 제가 원하는 목표인데
저런 방법이 비효율적이라 생각되서 다른 방법이 있는지 알고 싶습니다.

 의 이미지

어떤 측면에서 비효율적이라고 생각하시는지는 모르겠습니다만...

1. 규칙 없는 시퀀스에 대한 일반적인 선형 탐색 알고리즘의 시간복잡도는 O(n)입니다.
물론 정말로 에누리 없이 정확히 n에 비례하는 경우는 두 경우밖에 없는데,

1) 찾고자 하는 값이 시퀀스에 없거나.
2) 찾고자 하는 값을 마지막으로 조사한 곳에서 찾거나.

1)은 어쩔 수 없는 경우고 (시퀀스에 어떤 값이 없다는 걸 확신하려면 결국 다 찾아볼 수밖에 없습니다.)
2)는 운이 없는 경우죠.

실제로 시퀀스에 찾고자 하는 값이 단 하나 있는데 어디 있는지 전혀 단서를 찾을 수 없는 경우, 발견까지의 평균 탐색 횟수는 n/2라고 보시면 되겠습니다.

아무튼 NOT FOUND 메시지를 최종적으로 출력하기 위해서는 결국 n개의 원소를 다 볼 수밖에 없어요. 최소한 지금 널리 쓰이는 컴퓨터에서는 그렇습니다.

FOUND 메시지가 출력되는 경우에 대해서는 개선이 가능하군요. 찾고자 하는 값이 정확히 몇 개 있는지(count)를 꼭 알 필요가 없다면 루프를 끝까지 돌면서 세고 있을 이유가 없습니다. 그냥 찾자마자 빠져나오면 됩니다. 대충 아래와 같겠죠.

	int count = 0;
	for (int i = 0; i != 10; ++i) {
		if (test[i] == 7) {
			count = 1; // 어쨌든 한 개는 있음.
			break; // 찾자마자 빠져나갑시다.
		}
	}
	if (count != 0) { // 어차피 중요한 건 0이냐 아니냐 뿐이니까요.
		cout << "FOUND" << endl;
	}
	else {
		cout << "NOT FOUND" << endl;
	}

그래봤자 여전히 O(n)짜리 알고리즘입니다만 운이 좋아서 조금 빨리 끝나는 걸 기대해 볼 수는 있지요.
갯수를 정확히 세는 게 꼭 중요하다면 루프를 끝까지 돌리는 걸 피할 방법이 없습니다.

더 빠른 알고리즘을 바라십니까? 그러면 자료구조의 영역에 발을 들여놓아야 합니다.

https://en.wikipedia.org/wiki/Search_data_structure

시퀀스가 정렬되어 있기만 해도 이진 탐색 알고리즘을 쓰면 비용은 O(n)에서 O(log n)으로 크게 줄어들지요.
데이터가 물리 메모리 안에 무난히 다 들어올 정도의 크기라면 보통 그 정도면 충분합니다.
마침 질문자님의 코드는 배열 초기값을 오름차순으로 넣어서 이미 정렬이 되어 있네요.
이진 탐색도 이미 잘 구현된 게 있어요. C언어의 bsearch, C++의 binary_search 등.

http://en.cppreference.com/w/c/algorithm/bsearch
http://en.cppreference.com/w/cpp/algorithm/binary_search

C++의 equal_range를 쓰면 심지어 찾고자 하는 값이 정확히 몇 개 들어있는지도 O(log n)에 알 수 있지요. 원래 이진 탐색으로 가능한 거긴 한데 실제로 구현하는 건 약간 까다롭습니다.
직접 구현할 수 있으면 알고리즘 관련해서 초보딱지는 확실히 떼었다고 볼 수 있겠네요.

http://en.cppreference.com/w/cpp/algorithm/equal_range

탐색 대상이 늘었다 줄었다 하는 경우라면 일반적으로 Binary Search Tree가 있고요.

https://en.wikipedia.org/wiki/Binary_search_tree

운이 없으면 가끔 트리 균형이 안맞아서 탐색 비용이 늘어나는데 그걸 막으려면 Self-balancing binary search tree를 쓰면 됩니다.

https://en.wikipedia.org/wiki/Self-balancing_binary_search_tree

데이터 크기가 물리 메모리보다 더 커지면 이제 DBMS 개발자들이 수십년쯤 전에 연구했던 분야로 넘어갑니다. 근데 그 쯤 되면 그냥 DBMS를 쓰는 게 낫죠. sqlite 어때요? SQL 코딩도 재밌습니다.
물론 DBMS를 효율적으로 사용하는 법을 익히는 데에도 공부가 조금 필요합니다만.

https://www.sqlite.org

작성자의 이미지

제가 질문을 애매모호하게 했는데 정확한답변을 해주셔서 이해가 잘되네요. 확장된 답변까지 달아주셔서 감사합니다. 많은 도움이 되었어요.

작성자의 이미지

제가 질문을 애매모호하게 했는데 정확한답변을 해주셔서 이해가 잘되네요. 확장된 답변까지 달아주셔서 감사합니다. 많은 도움이 되었어요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.