Форум программистов, компьютерный форум CyberForum.ru

Нахождение max и min функции одной переменной - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
MonteCristo
0 / 0 / 0
Регистрация: 01.10.2011
Сообщений: 27
12.10.2011, 09:30     Нахождение max и min функции одной переменной #1
Нужна помощь.
Надо написать программу которая находить max и min функции с 1 переменой. (пользователь должен ввести функцию)
Очень прошу помочь. Не знаю как реализовать это на Си,прошу помочь,показать,объяснить.

Добавлено через 2 часа 37 минут
Ап (10 символов)

Добавлено через 14 часов 20 минут
ап(10 сим )
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
12.10.2011, 09:34     Нахождение max и min функции одной переменной #2
Цитата Сообщение от MonteCristo Посмотреть сообщение
Нужна помощь.
Надо написать программу которая находить max и min функции с 1 переменой. (пользователь должен ввести функцию)
Очень прошу помочь. Не знаю как реализовать это на Си,прошу помочь,показать,объяснить.

Добавлено через 2 часа 37 минут
Ап (10 символов)

Добавлено через 14 часов 20 минут
ап(10 сим )
Апбсолютный максимум или локальный на отрезке?
silent_1991
12.10.2011, 12:23
  #3

Не по теме:

Цитата Сообщение от MonteCristo Посмотреть сообщение
Ап (10 символов)
Цитата Сообщение от MonteCristo Посмотреть сообщение
ап(10 сим )
Пяти достаточно.



 Комментарий модератора 
2.14 Чтобы "поднять" тему в разделе и поиске по форуму, используйте осмысленные сообщения, например "Тема/проблема/задача актуальна". Если вы чего-то достигли в решении проблемы на этот момент, сообщите об этом.
MonteCristo
0 / 0 / 0
Регистрация: 01.10.2011
Сообщений: 27
12.10.2011, 16:03  [ТС]     Нахождение max и min функции одной переменной #4
"Апбсолютный максимум или локальный на отрезке?" локальный на отрезке. отрезок вводит тоже пользователь.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
12.10.2011, 21:27     Нахождение max и min функции одной переменной #5
MonteCristo, тогда еще вопрос. "Пользователь должен ввести функцию" - это вы как представляете?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
12.10.2011, 21:48     Нахождение max и min функции одной переменной #6
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
это вы как представляете?
Хоть вопрос и не ко мне, но я представляю это себе как парсер выражений, а это дело никто просто так писать не будет))
MonteCristo
0 / 0 / 0
Регистрация: 01.10.2011
Сообщений: 27
12.10.2011, 22:09  [ТС]     Нахождение max и min функции одной переменной #7
ясно) спасибо,постараюсь все же что то сам написать... если возникнут затруднения обращусь опять к вам ^^ )
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
12.10.2011, 22:25     Нахождение max и min функции одной переменной #8
У меня есть почти готовый парсер, но работает только с переменными, константами, скобками, и операторами(+,-,*,/,%,^). Т.е. в выражении не должно быть никаких функций типа sin.
Jack__
1 / 1 / 0
Регистрация: 06.03.2011
Сообщений: 7
13.10.2011, 07:05     Нахождение max и min функции одной переменной #9
Добавлено через 29 минут
Какие могут быть функции?
MonteCristo
0 / 0 / 0
Регистрация: 01.10.2011
Сообщений: 27
13.10.2011, 14:51  [ТС]     Нахождение max и min функции одной переменной #10
Цитата Сообщение от Chelioss Посмотреть сообщение
У меня есть почти готовый парсер, но работает только с переменными, константами, скобками, и операторами(+,-,*,/,%,^). Т.е. в выражении не должно быть никаких функций типа sin.
Это и нужно,всякие функции,sin,cos и т д не нужны.
например функция x1^2+x2^2. вот при x1+x2=1. Вот что то такое.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
13.10.2011, 17:34     Нахождение max и min функции одной переменной #11
Цитата Сообщение от MonteCristo Посмотреть сообщение
x1+x2=1
Это уравнение? Я не про уравнения говорил. Уравнения мой парсер не умеет решать.
А вот это
x1^2+x2^2
решит, если x1 и x2 имеют уже какое-то значение.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
13.10.2011, 17:43     Нахождение max и min функции одной переменной #12
Цитата Сообщение от Chelioss Посмотреть сообщение
Уравнения мой парсер не умеет решать.
Не проблема совместить ваш парсер и любой численный метод решения уравнений, хотя бы таблицей подстановки значений.
MonteCristo
0 / 0 / 0
Регистрация: 01.10.2011
Сообщений: 27
13.10.2011, 17:48  [ТС]     Нахождение max и min функции одной переменной #13
Цитата Сообщение от Chelioss Посмотреть сообщение
Это уравнение? Я не про уравнения говорил. Уравнения мой парсер не умеет решать.
А вот это
x1^2+x2^2
решит, если x1 и x2 имеют уже какое-то значение.
это одна из частей того что примерно нужно.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
13.10.2011, 17:59     Нахождение max и min функции одной переменной #14
Я не понял. Вам уравнение решать надо или значение функции вычислить?
MonteCristo
0 / 0 / 0
Регистрация: 01.10.2011
Сообщений: 27
13.10.2011, 18:43  [ТС]     Нахождение max и min функции одной переменной #15
мне надо что б программа могла найти max и min функции. функция может быть любая.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.10.2011, 19:04     Нахождение max и min функции одной переменной
Еще ссылки по теме:

C++ Поменять нахождение min среди двумерного массива, на нахождение min в каждой сточке
Работа с функциями. Нахождение min и max C++
C++ Нахождение Max и Min в строке двумерного массива

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
15.10.2011, 19:04     Нахождение max и min функции одной переменной #16
Замечания к программе:
В функции допускаются только символы вида '5', '-5', 'x', '-x', '(', ')', '+', '-', '*', '/', '^', '%'
Со скобками можно делать что угодно, если это не нарушает правил математики. Например, можно написать "2 + x ( ) ( ) ( ) - ( ( ) 5 )"
Степень может быть только больше или равной нулю.
Всё должно быть отделено пробелами.
Числа должны быть только целыми.
Если число или x должно быть отрицательным, то можно написать '-число' или '-x'. Пример уравнения: "-x + 5 + x ^ 2"
Границы могут быть только целыми числами. Нахождение min и max происходит по точкам a, a+1 ... b

Файлы с расширением .h должны именоваться так, как я напишу ниже.
Файл Node.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef NODE_H
#define NODE_H
 
template < class T >
class Node
{
    template < class T > friend class Stack;
public:
    Node( T );
private:
    T data;
    Node *nextPtr;
};
 
template < class T >
Node< T >::Node( T m_data )
: data( m_data ), nextPtr( 0 )
{
}
 
#endif

Файл Stack.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#ifndef STACK_H
#define STACK_H
 
#include "Node.h"
 
template < class T >
class Stack
{
public:
    Stack();
    ~Stack();
 
    void push( T );
    bool pop( T & );
    T peek() const;
    bool isEmpty() const;
private:
    Node< T > *firstPtr;
    Node< T > *lastPtr;
};
 
template < class T >
Stack< T >::Stack()
: firstPtr( 0 ), lastPtr( 0 )
{
}
template < class T >
Stack< T >::~Stack()
{
    Node< T > *currentPtr = firstPtr;
    Node< T > *tempPtr = currentPtr;
    while( currentPtr != 0 )
    {
        tempPtr = currentPtr;
        currentPtr = currentPtr->nextPtr;
        delete tempPtr;
    }
}
template < class T >
void Stack< T >::push( T m_data )
{
    Node< T > *newPtr = new Node< T >( m_data );
    if( isEmpty() )
        firstPtr = lastPtr = newPtr;
    else
    {
        lastPtr->nextPtr = newPtr;
        lastPtr = newPtr;
    }
}
template < class T >
bool Stack< T >::pop( T &m_data )
{
    if( isEmpty() )
        return false;
    else
    {
        Node< T > *tempPtr = lastPtr;
        if( firstPtr == lastPtr )
            firstPtr = lastPtr = 0;
        else
        {
            Node< T > *currentPtr = firstPtr;
            while( currentPtr->nextPtr != lastPtr )
                currentPtr = currentPtr->nextPtr;
            lastPtr = currentPtr;
            currentPtr->nextPtr = 0;
        }
        m_data = tempPtr->data;
        delete tempPtr;
        return true;
    }
}
template < class T >
bool Stack< T >::isEmpty() const
{
    return firstPtr == 0;
}
template < class T >
T Stack< T >::peek() const
{
    if( firstPtr != 0 )
        return lastPtr->data;
    else
        return 0;
}
 
#endif

Файл convertXtoValue.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <string>
 
void formatStr_xToValue( char *str, int value )
{
    char temp[ 50 ] = { 0 }; 
    char *beginStr = str; // сохраняем указатель str, т.е. дальше мы его будем изменять
    for( char *ptr = strchr( str, 'x' ); ptr != '\0'; ptr = strchr( str, 'x' ) )
    /* находим x ; пока находим x, т.е. ptr не равно 0; находим следующий x  */
    {
        *ptr = '\0'; // вместо x вставим 0
        strcpy( temp + strlen( temp ), str ); // копируем все, что после предыдущего x(или начала функции) и до текущего x
        itoa( value, temp + strlen( temp ), 10 ); // вставляем вместо x значение в конец temp
        str = ptr + 1; // пропускаем 0, который был раньше x. В итоге str указывает на оставшуюся часть функции после текущего x.
    }
    strcpy( temp + strlen( temp ), str ); // все, что осталось после последного x копируем в конец temp
    str = beginStr; // устанавливаем указатель в исходный указатель 
    strcpy( str, temp ); // форматированную функцию temp копируем в str
}

Файл InfixToPostfix.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "Stack.h"
#include <string>
 
bool isOperator( char symb );
bool isStrIsDigit( const char *str );
int precedence( char operator1, char operator2 );
 
void convertToPostfix( char *infix )
{
    int infixLen = strlen( infix );
    char postfix[ 100 ] = { 0 };
    int postfixLen = 0;
    Stack< char > stack;
    stack.push( '(' );
    infix[ infixLen ] = ' ';
    infix[ infixLen + 1 ] = ')';
    infix[ infixLen + 2 ] = '\0';
    infixLen += 2;
    char symb = 0;
 
    char *tokenPtr = strtok( infix, " " );
    while( tokenPtr != NULL )
    {
        if( isStrIsDigit( tokenPtr ) ) // если число
        {
            strcpy( postfix + postfixLen, tokenPtr );
            postfixLen += strlen( tokenPtr );
            postfix[ postfixLen ] = ' ';
            postfix[ postfixLen + 1 ] = '\0';
            ++postfixLen;
 
        }
        else if( *tokenPtr == '(' ) // если левая скобка
        {
            stack.push( *tokenPtr ); // заталкиваем левую скобку
        } 
        else if( isOperator( *tokenPtr ) ) // если оператор
        {
            while( isOperator( stack.peek() ) && // пока в конце стэка операторы
                1 != precedence( *tokenPtr, stack.peek() ) ) // и приоритеты этих операторов равно или больше
            {
                switch( precedence( *tokenPtr, stack.peek() ) ) // приоритет
                {
                case -1: // если текущий оператор имеет более низкий приоретер, чем оператор в стэке
                case 0: // если текущий оператор имеет одинаковый приоретер с оператором в стэке
                    stack.pop( symb ); // выталкиваем
                    postfix[ postfixLen ] = symb; // и вставляем в postfix
                    postfix[ postfixLen + 1 ] = ' ';
                    postfix[ postfixLen + 2 ] = '\0';
                    postfixLen += 2;
                    break;
                case 1: 
                    // оставляем оператор в стэке и выходим из цикла
                    // сюда мы не должны попасть из-за условия в цикле
                    break;
                }
            }
            stack.push( *tokenPtr ); // заталкиваем текущий оператор
        }
        else if( *tokenPtr == ')' ) // если правая скобка
        {
            while( isOperator( stack.peek() ))  // пока в конце стэка оператор
            {
                stack.pop( symb ); // выталкиваем оператор
                postfix[ postfixLen ] = symb; // и вставляем в postfix
                postfix[ postfixLen + 1 ] = ' ';
                postfix[ postfixLen + 2 ] = '\0';
                postfixLen += 2;
            }
            stack.pop( symb ); // выталкиваем левую скобку
        }   
        tokenPtr = strtok( NULL, " " );
    }
    strcpy( infix, postfix );
    infix[ strlen( infix ) - 1 ] = '\0'; //убираем последний пробел
}

Файл main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <string>
 
void searchMinMax( char *function, int a, int b, double &min, double &max );
 
int main()
{
    setlocale( LC_ALL, "Russian" );
    
    const int sizeFunction = 50;
    char function[ sizeFunction ];
    std::cout << "Введите функцию( все символы должны быть отделены пробелами ):" << std::endl;
    std::cin.getline( function, 50, '\n' );
    //strcpy( function, "x + 2 * x / 5" );
    std::cout << "Введите через пробел границы отрезка [a,b]: " << std::endl;
    int a = 0;
    int b = 0;
    std::cin >> a >> b;
 
    double min = 0;
    double max = 0;
    searchMinMax( function, a, b, min, max );
 
    std::cout << "Минимум на отрезке [a,b] составляет: " << min << std::endl;
    std::cout << "Максимум на отрезке [a,b] составляет: " << max << std::endl;
 
    system( "pause" );
    return 0;
}

Файл OtherFunction.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <cmath>
 
bool isOperator( char symb )
{
    if( symb == '+' || symb == '-' || symb == '*' || symb == '/' ||
        symb == '^' || symb == '%' )
        return true;
    return false;
}
bool isDigit( char symb )
{
    if( symb >= '0' && symb <= '9' )
        return true;
    return false;
}
double calculate( double y, double x, char operat )
{
    double result = 0;
    switch( operat )
    {
    case '+':
        result = y + x;
        break;
    case '-':
        result = y - x;
        break;
    case '*':
        result = y * x;
        break;
    case '/':
        result = y / x;
        break;
    case '^':
        result = pow( y, x );
        break;
    case '%':
        result = ( int )y % ( int )x;
        break;
    }
    return result;
}
 
bool isStrIsDigit( const char *str )
{
    if( *str == '-' )
    {
        ++str;
        if( !isDigit( *str ) &&  *str != '-' )
            return false;
        else if( *str == '-' )
        {
            ++str;
            if( !isDigit( *str ) )
                return false;
        }
    }
    for( ; !isDigit( *str ) && *str; ++str )
        return false;
    return true;
}
int precedence( char operator1, char operator2 )
{
    if( operator1 == '+' || operator1 == '-' )
        if( operator2 == '+' || operator2 == '-' )
            return 0;
        else // * / ^ %
            return -1;
    else // * / ^ %
        if( operator2 == '+' || operator2 == '-' )
            return 1;
        else // * / ^ %%
            return 0;
}

Файл PostfixToResult.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "Stack.h"
#include <cmath>
#include <string>
 
bool isOperator( char symb );
bool isStrIsDigit( const char *str );
double calculate( double y, double x, char operat );
 
double evaluatePostfixExpression( char *postfix )
{
    Stack< double > stack;
    double result = 0;
    double x = 0;
    double y = 0;
 
    char *tokenPtr = strtok( postfix, " " );
 
    while( tokenPtr != NULL )
    {
        if( isStrIsDigit( tokenPtr )  )
        {
            if( *tokenPtr == '-' && *( tokenPtr + 1 ) == '-' ) // минус на минус дает пробелы(плюс)!
                *tokenPtr = *( tokenPtr + 1 ) = ' ';
            stack.push( atoi( tokenPtr ) );
        }
        else if( isOperator( *tokenPtr ) )
        {
            stack.pop( x );
            stack.pop( y );
            result = calculate( y, x, *tokenPtr );
            stack.push( result );
        }
        tokenPtr = strtok( NULL, " " );
    }
    stack.pop( result );
    return result;
}

Файл searchMinMax.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <string>
 
void convertToPostfix( char *infix );
double evaluatePostfixExpression( char *postfix );
void formatStr_xToValue( char *str, int value );
 
void searchMinMax( char *function, int a, int b, double &min, double &max )
{
    char str[ 50 ] = { 0 };
    double result = 0;
    
    strcpy( str, function ); // скопируем в str исходную функцию
    formatStr_xToValue( str, a ); // заменяем все x на текущее значение, т.е. границу a
    convertToPostfix( str ); // преобразуем инфиксную нотацию в постфиксную нотацию
    min = max = evaluatePostfixExpression( str ); // вычисляем результат постфиксной нотации
    
    for( int i = a + 1; i <= b; ++i )
    {
        strcpy( str, function ); // скопируем в str исходную функцию
        formatStr_xToValue( str, i ); // заменяем все x на текущее значение i
        convertToPostfix( str ); // преобразуем инфиксную нотацию в постфиксную нотацию
        result = evaluatePostfixExpression( str ); // вычисляем результат постфиксной нотации
        if( result > max )
            max = result;
        else if( result < min )
            min = result;
    }
}
Yandex
Объявления
15.10.2011, 19:04     Нахождение max и min функции одной переменной
Ответ Создать тему
Опции темы

Текущее время: 12:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru