Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.04.2010, 10:05   #1
АдексейКо
Новичок
Джуниор
 
Регистрация: 20.04.2010
Сообщений: 4
Лампочка Алгоритм программы

Обучаюсь С. Есть такая вот программа с понимаем программы, прошу помочь мне описать её алгоритм, принцип работы.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
 
 
/********************************************************************/
#define MAX_LINE_SIZE           1024
#define LINES_DEF_SIZE          256
#define MAX_DIFF                        0.0001
 
 
/********************************************************************/
typedef struct {
        double x, y;
        int flag;
} point_flag_t;
 
typedef struct {
        int size, max_size;
        char **lines;
} objects_t;
 
#define objects_size(arg_pobj)                  ((arg_pobj)->size)
#define objects_line(arg_pobj,arg_i)    ((arg_pobj)->lines[(arg_i)])
 
 
/********************************************************************/
void do_process( const char *in_name, const char *out_name );
 
int read_objects_file( objects_t *pobj, const char *name );
void free_objects( objects_t *pobj );
 
int parse_x_y( const char *buf, double *px, double *py );
 
 
/********************************************************************/
int main( int argc, char *argv[] ) {
 
argc--; argv++;
 
if ( argc != 2 ) {
        fprintf( stderr, "Usage: search in.txt out.txt" );
        exit( 2 ) ;
}
 
do_process( argv[0], argv[1] );
return 0;
 
} /* main() */
 
 
/********************************************************************/
void do_process( const char *in_name, const char *out_name ) {
 
int i, j;
int errcode;
 
int line_size;
char *line;
 
int obj_size;
objects_t obj;
 
double x, y;
point_flag_t *ppoint= NULL;
FILE *fout= NULL;
 
 
/* Read */
if ( read_objects_file( &obj, in_name ) ) { goto err_read; }
 
/* Check */
obj_size= objects_size( &obj );
if ( obj_size == 0 ) { goto err_no_obj; }
 
/* Allocate points */
ppoint= (point_flag_t*)malloc( obj_size*sizeof(point_flag_t) );
if ( ppoint == NULL ) { goto err_nomem; }
 
/* Parse x,y and setup point */
for ( i= 0; i<obj_size; i++ ) {
        if ( parse_x_y( objects_line( &obj, i ), &x, &y ) ) { goto err_format; }
        ppoint[i].x= x; ppoint[i].y= y;
        ppoint[i].flag= 0;
}
 
/* Compare loop */
for ( i= 0; i<obj_size; i++ ) {
        for ( j= i+1; j<obj_size; j++ ) {
                if ( fabs( ppoint[i].x-ppoint[j].x )<=MAX_DIFF &&
                        fabs( ppoint[i].y-ppoint[j].y )<=MAX_DIFF ) {
                        ppoint[i].flag= ppoint[j].flag= 1;
                        /* printf( "near %d %d\n", i, j ); */
                        break;
                }
        }
}
 
/* Create out */
fout= fopen( out_name, "wb" );
if ( fout == NULL ) { goto err_create; }
 
/* Write out loop */
for ( i= 0; i<obj_size; i++ ) {
        if ( !ppoint[i].flag ) { continue; }
 
        line= objects_line( &obj, i );
        line_size= strlen( line );
        errcode= fprintf( fout, "%s\n", line );
        if ( line_size+1 != errcode ) { goto err_write; }
 
}
 
/* Close out */
if ( fclose( fout ) ) { goto err_close; }
fout= NULL;
 
/* Free ppoint */
free( ppoint ); ppoint= NULL;
 
return;
 
 
/* Processing errors */
err_read:
fprintf( stderr, "Error reading file\n" );
goto err_all;
 
err_no_obj:
fprintf( stderr, "No objects\n" );
goto err_all;
 
err_nomem:
fprintf( stderr, "No memory\n" );
goto err_all;
 
err_format:
fprintf( stderr, "Invalid format\n" );
goto err_all;
 
err_create:
fprintf( stderr, "Error creating file\n" );
goto err_all;
 
err_write:
fprintf( stderr, "Error writing file\n" );
goto err_all;
 
err_close:
fprintf( stderr, "Error closing file\n" );
goto err_all;
 
err_all:
exit( 1 );
 
} /* do_process() */
АдексейКо вне форума Ответить с цитированием
Старый 20.04.2010, 10:06   #2
АдексейКо
Новичок
Джуниор
 
Регистрация: 20.04.2010
Сообщений: 4
По умолчанию

Код:
/********************************************************************/
int read_objects_file( objects_t *pobj, const char *name ) {
 
int buf_size, max_size;
char buf[MAX_LINE_SIZE], *line, **lines;
FILE *fin= NULL;
 
 
/* Init */
pobj->size= 0; pobj->max_size= 0;
pobj->lines= NULL;
 
/* Open */
fin= fopen( name, "r" );
if ( fin == NULL ) { goto err_read; }
 
/* Loop */
for ( ; ; ) {
        
        /* Read line */
        if ( fgets( buf, sizeof(buf), fin ) == NULL ) {
                if ( feof( fin ) ) { break; }
                goto err_read;
        }
        buf_size= strlen( buf );
        if ( buf_size>0 && buf[buf_size-1] == '\n' ) { buf[--buf_size]= '\0'; }
 
        /* Check space and realloc */
        if ( pobj->size >= pobj->max_size ) {
 
                max_size= (pobj->max_size!=0) ? 2*pobj->max_size : LINES_DEF_SIZE;
                lines= (char**)realloc( pobj->lines, max_size*sizeof(char*) );
                if ( lines == NULL ) { goto err_nomem; }
                        
                pobj->max_size= max_size; pobj->lines= lines;
 
        }
        
        /* Store */
        line= malloc( buf_size+1 );
        if ( line == NULL ) { goto err_nomem; }
        memcpy( line, buf, buf_size+1 );
        pobj->lines[pobj->size]= line; pobj->size++;
 
}
 
/* Close */
if ( fclose( fin ) ) { goto err_close; }
fin= NULL;
 
/* Return */
return 0;
 
 
/* Processing errors */
err_read:
err_close:
err_nomem:
return 1;
 
} /* read_objects_file() */
 
 
/********************************************************************/
void free_objects( objects_t *pobj ) {
 
int i;
 
 
for ( i= 0; i<pobj->size; i++ ) {
        if ( pobj->lines[i] != NULL ) { free( pobj->lines[i] ); }
}
free( pobj->lines );
 
pobj->size= pobj->max_size= 0;
pobj->lines= NULL;
        
} /* free_objects() */
 
 
/********************************************************************/
int parse_x_y( const char *buf, double *px, double *py ) {
 
int buf_size;
char *endptr;
 
 
/* Check line */        
buf_size= strlen( buf );
if ( buf_size != 408 ) { return 1; }
 
*px= strtod( &buf[238], &endptr );
if ( *px == 0.0 ) {
        if ( &buf[238] == endptr ) { return 1; }
}
 
*py= strtod( &buf[252], &endptr );
if ( *py == 0.0 ) {
        if ( &buf[252] == endptr ) { return 1; }
}
 
return 0;
 
} /* parse_x_y() */
АдексейКо вне форума Ответить с цитированием
Старый 20.04.2010, 10:27   #3
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию


При таких размерах кода вам бесплатно помочь могут только уж самые энтузиасты, но таких мало! Тем более что даже задания нет и непонятно что программа хотя бы вообще должна делать!
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 20.04.2010, 10:48   #4
АдексейКо
Новичок
Джуниор
 
Регистрация: 20.04.2010
Сообщений: 4
По умолчанию

Заданием программы было считать данные с текстового файла, эти данные содержат координаты для каждого определённого объекта, затем посредством сравнения данных между собой нужно было найти те данные, координаты X и Y которых были практическими схожими, допускалось различие в 0.0001 между X-ми и Y-ми. В итог мы должны получить список схожих значений. после отсеивания.

Сама программа рабочая, но я хочу разобраться в ней.

Последний раз редактировалось MaTBeu; 20.04.2010 в 11:58.
АдексейКо вне форума Ответить с цитированием
Старый 21.04.2010, 00:55   #5
silent_1991
Пользователь
 
Регистрация: 06.11.2009
Сообщений: 68
По умолчанию

Честно говоря особо не разбирался, но ИМХО для такого простого задания такой длинный код с кучей переменных и функций... Что-то меня это смущает... Всё намного легче можно реализовать... Или может я не правильно понял задание? Как я понял при таком выходном файле:

0 2
1 4
3 3.0001
5 6
2 2.0001
4.0001 4
10 40
5.5 5.5001

мы должны получить такой выходной файл:

3 3.0001
2 2.0001
4.0001 4
5.5 5.5001
?
silent_1991 вне форума Ответить с цитированием
Старый 21.04.2010, 08:21   #6
АдексейКо
Новичок
Джуниор
 
Регистрация: 20.04.2010
Сообщений: 4
По умолчанию

Немножко не так. Вот пример.
2 4
3.0001 6
8 4.0001
8.0001 4
1 7
2 9.0001
3 5
2.0001 9

В итоге должно вывести:
8 4.0001
8.0001 4
2 9.0001
2.0001 9
АдексейКо вне форума Ответить с цитированием
Старый 21.04.2010, 10:20   #7
silent_1991
Пользователь
 
Регистрация: 06.11.2009
Сообщений: 68
По умолчанию

А, т.е. сравнение происходит по столбцам. Понятно.
silent_1991 вне форума Ответить с цитированием
Старый 21.04.2010, 11:53   #8
silent_1991
Пользователь
 
Регистрация: 06.11.2009
Сообщений: 68
По умолчанию

И обязательно, чтобы в двух записях каждая пара (x1, x2), (y1, y2) различалась не более чем на 0.1?

Сорри за мультипост, в последнее время сидел на форуме, на котором при написании нового сообщения оно добавляется к предыдущему (если конечно автором предыдущего сообщения является автор последнего).

Последний раз редактировалось silent_1991; 21.04.2010 в 12:00.
silent_1991 вне форума Ответить с цитированием
Старый 21.04.2010, 17:03   #9
silent_1991
Пользователь
 
Регистрация: 06.11.2009
Сообщений: 68
По умолчанию

Конечно понимаю, что далеко не оптимальный вариант, многие бы меня за подобное извращение подвесили за одно место, но писал в порыве вдохновения, поэтому что вышло - то вышло))) Уверен, что могу это дело оптимизировать (особенно чтение из файла), да и неплохо было бы через динамические массивы это реализовать, но, честно говоря, лень)))... Да и ИМХО, это более понятно, чем представленный топикстартером вариант)))
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define LEN 1024

int main()
{
    FILE *fin;
    
    if ((fin = fopen("coords.in", "r")) == NULL)
    {
        printf("Oshibka otkritiya faila!");
        getch();
        return -1;
    }
    
    double xy[LEN][2];
    double result[LEN][2];
    char number1[20], number2[20];
    char buffer[20];
    int i, j, k;
    int P, R;
    int key = 0;
    
    P = 0;
    
    while (!feof(fin))   
    {
        for (i = 0; i < 20; i++)
        {
            buffer[i] = ' ';
            number1[i] = ' ';
            number2[i] = ' ';
        }
        
        fgets(buffer, 20, fin);
        
        i = 0;
        j = 0;
        
        while (buffer[i] != ' ')
        {
            number1[i] = buffer[i];
            i++;
        }
        
        i++;
        
        while (buffer[i] != '\0')
        {
            number2[j] = buffer[i];
            i++;
            j++;
        }
        
        xy[P][0] = atof(number1);
        xy[P][1] = atof(number2);
        P++;
    }
    
    fclose(fin);
    
    for (i = 0, R = 0; i < P; i++)
    {
        for (j = i + 1; j < P; j++)
        {
            if ((fabs(xy[i][0] - xy[j][0]) <= 1.01/10000.0) && (fabs(xy[i][1] - xy[j][1]) <= 1.01/10000.0))
            {
                if ((fabs(xy[i][0] - xy[j][0]) == 0) && (fabs(xy[i][1] - xy[j][1]) == 0))
                {
                    result[R][0] = xy[i][0];
                    result[R][1] = xy[i][1];
                    
                    for (k = 0; k < R; k++)
                    {
                        if ((result[k][0] == result[R][0]) && (result[k][1] == result[R][1]))
                        {
                            key = 1;
                            break;
                        }
                    }
                    
                    if (!key)
                    {
                        R++;
                    }
                    
                    key = 0;
                }
                else
                {
                    result[R][0] = xy[i][0];
                    result[R][1] = xy[i][1];
                    
                    for (k = 0; k < R; k++)
                    {
                        if ((result[k][0] == result[R][0]) && (result[k][1] == result[R][1]))
                        {
                            key = 1;
                            break;
                        }
                    }
                    
                    if (!key)
                    {
                        R++;
                    }
                    
                    result[R][0] = xy[j][0];
                    result[R][1] = xy[j][1];
                    
                    for (k = 0; k < R; k++)
                    {
                        if ((result[k][0] == result[R][0]) && (result[k][1] == result[R][1]))
                        {
                            key = 1;
                            break;
                        }
                    }
                    
                    if (!key)
                    {
                        R++;
                    }
                }
            }
        }
    }
    
    FILE *fout;
    
    if ((fout = fopen("coords.out", "w")) == NULL)
    {
        printf("Oshibka zapisi v fail!");
        getch();
        return -1;
    }
    
    for (i = 0; i < R; i++)
    {
        fprintf(fout, "%.4f %.4f\n", result[i][0], result[i][1]);
    }
    
    fclose(fout);
    
    getch();
    return 0;
}

Последний раз редактировалось silent_1991; 21.04.2010 в 17:12.
silent_1991 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Алгоритм для программы Kostik777 Помощь студентам 2 15.01.2010 12:09
составить алгоритм программы Alfis Паскаль, Turbo Pascal, PascalABC.NET 1 22.12.2008 00:51
Алгоритм программы. Небесный Паскаль, Turbo Pascal, PascalABC.NET 2 16.12.2007 10:23
Алгоритм программы. Небесный Свободное общение 0 09.12.2007 23:30