Технический форум

Технический форум (http://www.tehnari.ru/)
-   C/C++/С# (http://www.tehnari.ru/f42/)
-   -   Задача по "С" (http://www.tehnari.ru/f42/t24192/)

manuchehr 29.04.2009 19:55

Задача по "С"
 
Программа "С"

Есть текстовый файл неопределенной длины- стандартный ввод(stdin), нужно отсортировать его строки в лексикографическом порядке по возрастанию и вывести их на стандартный вывод(stdout).

Программа должна запускаться из командной строки и считывать строки текста пока пользователь не сигнализирует о конце файла(стандартного ввода)комбинацией Ctrl+D (unix)или Ctrl+Z (windows).
Необходимо использовать динамическую память для хранения считываемых строк, так как заранее не известно их количество.
Программа сортирует считанные строки любым алгоритмом сортировки и выводит их на stdout.
Лексикографическое сравнение строк:
"ABC"<"ABCD","ABC"="ABC","ABC"<"ABD"
Для его выполнения можно воспользоваться функцией strmcp().

blake 29.04.2009 21:47

Пиши в асю 803-866 договаримся!

csbwalker 01.05.2009 00:55

Посмотри на мой пост здесь:
http://www.tehnari.ru/f22/t24167/index2.html#post199170

Тут практически идентичная задача, единственное отличие - сигнализация конца стандартного ввода
Там концом ввода считается ввод пустой строки, у тебя - комбинация. Копай функцию int enterElement() в том же листинге, напиши что понял\не понял - если будет время, попробую объяснить.

Дария 15.05.2009 01:06

ПОЖАЛУЙСТА!!!Помогите написать программу на С. очень нужно для экзамена. заранее благодарю.
Дерево выражения вывести (используя обход дерева) в инфиксной (обычной) форме записи, учитывать приоритет операции. выражение (2+3)*4.

Дария 19.05.2009 21:27

Ребята!!! пожалуйста помогите написать прогу!!)

csbwalker 21.05.2009 12:55

Цитата:

Сообщение от Дария (Сообщение 203074)
ПОЖАЛУЙСТА!!!Помогите написать программу на С. очень нужно для экзамена. заранее благодарю.
Дерево выражения вывести (используя обход дерева) в инфиксной (обычной) форме записи, учитывать приоритет операции. выражение (2+3)*4.

Код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct element
{
        int number;
        char operation;
        struct element *left;
        struct element *right;
};

int findLastOperation(char str[], int count)
{
int current = 0, pri, i;
int number;
int minimal = -1;

        for(i = 0; i < count; i++)
        {
                switch(str[i])
                {
                        case '(':
                                current += 2;
                                break;
                        case ')':
                                current -= 2;
                                break;
                        case '*':
                        case '/':
                                pri = current + 1;
                                if(((minimal >= 0) && (pri < minimal)) || (minimal < 0))
                                {
                                        number = i;
                                        minimal = pri;
                                }
                                break;
                        case '+':
                        case '-':
                                pri = current;
                                if(pri == 0)
                                        return i;
                                if(((minimal >= 0) && (pri < minimal)) || (minimal < 0))
                                {
                                        number = i;
                                        minimal = pri;
                                }
                                break;
                        default:
                                break;
                }
        }
        if(minimal >= 0)
                return number;
        else
                return -1;
}

int stringtoi(char str[], int count)
{
char tmp[count + 1];
        if(str[0] == '(')
                str++, count--;
        if(str[count - 1] == ')')
                count--;

        strncpy(tmp, str, count);
        tmp[count] = '\0';

        return atoi(tmp);
}

struct element *build(char str[], int count)
{
struct element *el = (struct element *)malloc(sizeof(struct element));
int n = findLastOperation(str, count);

        if(n == -1)
        {
                el->operation = 0;
                el->number = stringtoi(str, count);
        } else
        {
                el->operation = str[n];
                el->left = build(str, n);
                el->right = build(str + n + 1, count - n - 1);
        }
        return el;
}

void printTree(struct element *el, int n)
{
int i;
        for(i = 0; i < n; i++)
                putchar(' ');
        putchar('|');
               
        if(el->operation == 0)
        {
               
                printf("%d\n", el->number);
        } else
        {
               
                printf("%c\n", el->operation);
                printTree(el->left, n + 1);
                printTree(el->right, n + 1);
        }
}

int main()
{
char str[] = "(2+3)*4";
struct element *tree = build(str, strlen(str));

        printTree(tree, 0);

        return 0;
}

Выражение задаётся в main строкой char str[] = "(2+3)*4";.

бородёнок 24.05.2009 20:17

помогите с задачей на си...
задача: Строки текста, считанных с stdin, сохранить в двусвязный список, массив. Результат на stdout, реверсировать на выводе.
заранее благодарен.

csbwalker 01.06.2009 11:09

По просьбе Дарии - откомментрированная программа с построением дерева выражений:

Код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Структура для хранения элемента бинарного дерева */
struct element
{
        int number;            /* Хранимое число */
        char operation;        /* Код операции, которую необходимо выполнить что бы получить
                                  из дочерних элементов число */
        struct element *left;  /* Указатель на левое поддерево */
        struct element *right;  /* Указатель на правое поддерево */
};

/* Функция для определения в строке позиции операции с наименьшим приоритетом (с учетом скобок) */
/* На входе - массив символов в котором хранится строка, количество символов в строке */
/* Примечание - при обработке строки не учитывается концевой 0-маркер, поэтому функция может обрабатывать
  отдельные части строки */
int findLastOperation(char str[], int count)
{
int current = 0, pri, i, number, minimal = -1;

        for(i = 0; i < count; i++) /* Обработка всех символов строки */
        {
                switch(str[i]) /* Действия в зависимости от кода текущего символа */
                {
                        case '(':
                                current += 2; /* Скобка открывается. Увеличиваем базовый приоритет. */
                                break;
                        case ')':
                                current -= 2; /* Скобка закрывается. Уменьшаем базовый приоритет. */
                                break;
                        case '*':
                        case '/': /* Умножение и деление - приоритетные операции,
                                    к базовому приоритету прибавляем 1 и проверяем, не является
                                    ли приоритет текущей операции минимальным из уже просмотренных,
                                    если да - обновляем указатель на минимальный и значение приоритет */
                                pri = current + 1;
                                if(((minimal >= 0) && (pri < minimal)) || (minimal < 0))
                                {
                                        number = i;
                                        minimal = pri;
                                }
                                break;
                        case '+':
                        case '-':
                                /* Действия аналогичны умножению и делению, но приоритет не увеличивается на 1 */
                                pri = current;
                                if(pri == 0) /* Если приоритет текущей операции 0 - то он заранее минимален, */
                                        return i; /* поэтому можно не продолжать дальнейший поиск */
                                if(((minimal >= 0) && (pri < minimal)) || (minimal < 0))
                                {
                                        number = i;
                                        minimal = pri;
                                }
                                break;
                        default: /* Если символ - не операция */
                                break;
                }
        }
        if(minimal >= 0)
                return number; /* Возвращаем номер позиции */
        else
                return -1; /* Если minimal=-1 - то не было найдено ни одно операции */
}

/* Функция преобразования строки в целое число */
/* Учитывает возможность наличия открывающейся в начале или закрывающейся в конце скобки */
int stringtoi(char str[], int count)
{
char tmp[count + 1]; /* Временный буфер для строки */
        while(str[0] == '(') /* Убираем все скобки в начале */
                str++, count--;
        while(str[count - 1] == ')')  /* Убираем все скобки в конце */
                count--;

        strncpy(tmp, str, count); /* Копируем получившуюся после обрезки строку во временный буфер tmp */
        tmp[count] = '\0'; /* Ставим концевой 0-маркер после строки в буфере, что бы получить стандартную C-строку */

        return atoi(tmp); /* Возвращаем результат преобразования стандартной C-строки в целое число */
}

/* Рекурсивная функция построяния дерева */
/* На входе - обрабатываемая строка (возможно без 0-маркера), количество символов в строке */
struct element *build(char str[], int count)
{
struct element *el = (struct element *)malloc(sizeof(struct element)); /* Создаем новый элемент и выделяем под него память */
int n = findLastOperation(str, count); /* Ищем операцию с минимальным приоритетом - по ней будем производить разбивку */

        if(n == -1) /* Если операция не найдена - значит переданная строка это просто число */
        {
                el->operation = 0; /* Операции нет - следовательно записываем в код операции 0 */
                el->number = stringtoi(str, count); /* Записываем число */
        } else /* Если операция найдена - нужно производить дальнейшую разбивку */
        {
                el->operation = str[n]; /* Записываем в код операции код найденного символа операции */
                el->left = build(str, n); /* Вызываем функцию построения левого поддерева из левой части строки */
                el->right = build(str + n + 1, count - n - 1); /* Вызываем функцию построения правого поддерева из правой части строки */
        }
        return el; /* Возвращаем получившийся результат */
}

/* Рекурсивная функция для вывода бинарного дерева на экран */
/* На входе - указатель на начало поддерева, смещение при печати */
void printTree(struct element *el, int n)
{
int i;
        for(i = 0; i < n; i++) /* Печатаем пробелы для смещения*/
                putchar(' ');
        putchar('|');
               
        if(el->operation == 0) /* Если код операции не записан - значит это просто число, выводим его */
        {
               
                printf("%d\n", el->number);
        } else /* Если код операции записан - значит, выводим этот код на экран и запускаем обработку левого
                и правого поддеревьев с большим смещением чем текущее */
        {
               
                printf("%c\n", el->operation);
                printTree(el->left, n + 1);
                printTree(el->right, n + 1);
        }
}

int main()
{
char str[] = "(2+3)*4"; /* Задаем обрабатываемую строку, обязательно без пробелов*/
struct element *tree = build(str, strlen(str)); /* Строим дерево по заданной строке */

        printTree(tree, 0); /* Выводим дерево на экран */

        return 0;
}

P.S. я там по ходу дела одно исправление сделал - что бы если что прога могла и вложенные скобки обрабатывать, а именно в двух местах заменил if на while (оба раза - в функции stringtoi).

pron 22.11.2012 17:35

Цитата:

Сообщение от manuchehr (Сообщение 198866)
Программа "С"

Есть текстовый файл неопределенной длины- стандартный ввод(stdin), нужно отсортировать его строки в лексикографическом порядке по возрастанию и вывести их на стандартный вывод(stdout).

Программа должна запускаться из командной строки и считывать строки текста пока пользователь не сигнализирует о конце файла(стандартного ввода)комбинацией Ctrl+D (unix)или Ctrl+Z (windows).
Необходимо использовать динамическую память для хранения считываемых строк, так как заранее не известно их количество.
Программа сортирует считанные строки любым алгоритмом сортировки и выводит их на stdout.
Лексикографическое сравнение строк:
"ABC"<"ABCD","ABC"="ABC","ABC"<"ABD"
Для его выполнения можно воспользоваться функцией strmcp().

Чувак скинь пожалуйста код проги, очень надо, у меня такая же, а вот как написать даже не представляю, буду очень благодарен!


Часовой пояс GMT +4, время: 13:28.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.