tomyamaのブログ

日記・雑記。

C言語 bsearch() ソートされた配列を二分木検索 (binary search) する

C言語の「bsearch()関数」のサンプルプログラムです。

 

 

 

  • bsearch() ソートされた配列を二分木検索 (binary search) する
    • POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD
    • #include <stdlib.h>
    • void *bsearch( const void *key, const void *base, size_t nmemb, size_t size, int ( *compare )( const void *arg1, const void *arg2 ) );
    • compareが指す関数は次の値を返さなければならない
      • 戻り値 意味
        0より小さい arg1がarg2より小さい場合
        0 arg1とarg2が等しい場合
        0より大きい arg1がarg2より大きい場合

         


目次


サンプルコード

[bsearch.c]

#include <stdlib.h>         /* bsearch() */
#include <ctype.h>          /* tolower() */
#include <stdio.h>


typedef enum{
    FALSE = 0,
    TRUE  = 1
} bool_e;


typedef enum{
    CH_OTHER = 0,
    CH_ALPHA,
    CH_NUM
} char_type_e;


int charCompare( const void *a, const void *b );
bool_e isAlphabet( char ch );
bool_e isNumber( char ch );
char_type_e whatTypeOfChar( char ch );
char getInput( void );


int main( void )
{
    char        ch;
    char_type_e t;

    printf( "*** It ends when you enter a character that is neither alphabetic nor numeric. ***\n" );
    do{
        ch = getInput();

        t = whatTypeOfChar( ch );
        switch( t ){
        case CH_ALPHA:
            printf( " `%c' is alphabet.\n", ch );
            break;
        case CH_NUM:
            printf( " `%c' is number.\n", ch );
            break;
        default:
            printf( " `%c' is neither an alphabet nor a number.\n", ch );
        }
    }while( t != CH_OTHER );

    return 0;
}


/* 2つの文字を比較する */
int charCompare( const void *a, const void *b )
{
    return *( char *)a - *( char *)b ;
}


bool_e isAlphabet( char ch )
{
    static char alphabet = "abcdefghijklmnopqrstuvwxyz";
    void *ptr;
    bool_e bRet;

    /* ソートされた配列を二分木検索 (binary search) する */
    ptr = bsearch( &ch, alphabet, 26, sizeof( char ), charCompare );
    bRet = TRUE;
    if( ptr == NULL )
        bRet = FALSE;

    return bRet;
}


bool_e isNumber( char ch )
{
    static char number = "0123456789";
    void *ptr;
    bool_e bRet;

    /* ソートされた配列を二分木検索 (binary search) する */
    ptr = bsearch( &ch, number, 10, sizeof( char ), charCompare );
    bRet = TRUE;
    if( ptr == NULL )
        bRet = FALSE;

    return bRet;
}


char_type_e whatTypeOfChar( char ch )
{
    char_type_e chType = CH_OTHER;
    if( isAlphabet( ch ) )
        chType = CH_ALPHA;
    else if( isNumber( ch ) )
        chType = CH_NUM;

    return chType;
}


char getInput( void )
{
    char ch;

    fputs( "char?: ", stdout );  fflush( stdout );
    scanf( " %c", &ch );            /* 頭のホワイトスペースは無視 */
//  fseek( stdin, 0L, SEEK_END );   /* 残りの入力は捨てる */
    while( getchar() != '\n' );     /* 残りの入力は捨てる */
    ch = tolower( ch );             /* 大文字小文字の違いは無視 */

    return ch;
}

 

実行例

Cygwin 3.3.6-1, gcc (GCC) 11.3.0

$ gcc -Wall -O2 -o bsearch_cygwin bsearch.c
$
$ ./bsearch_cygwin.exe
*** It ends when you enter a character that is neither alphabetic nor numeric. ***
char?: 0
 `0' is number.
char?:  1
 `1' is number.
char?:   89
 `8' is number.
char?: 9
 `9' is number.
char?: a
 `a' is alphabet.
char?:  b
 `b' is alphabet.
char?:   y
 `y' is alphabet.
char?:    z
 `z' is alphabet.
char?:     Z
 `z' is alphabet.
char?:      A
 `a' is alphabet.
char?:       +
 `+' is neither an alphabet nor a number.
$

 

CentOS Stream 9, gcc (GCC) 11.3.1

$ gcc -Wall -O2 -o bsearch_centos9 bsearch.c
$
$ ./bsearch_centos9
*** It ends when you enter a character that is neither alphabetic nor numeric. ***
char?: abc
 `a' is alphabet.
char?: +123xyz
 `+' is neither an alphabet nor a number.
$

 

Microsoft Windows 10, Visual Studio 2022, x86 Native Tools Command Prompt for VS 2022

>cl /nologo /utf-8 /Fe:bsearch_msvc bsearch.c
bsearch.c
>bsearch_msvc.exe
*** It ends when you enter a character that is neither alphabetic nor numeric. ***
char?:  a
 `a' is alphabet.
char?: X
 `x' is alphabet.
char?: -
 `-' is neither an alphabet nor a number.

>