@Artem_r66

Как правильно сделать функцию для повторяющихся действий?

Здравсвуйте, подскажите как сделать отдельную функцию для повторяющихся действий.
Написал программу:
using System;

namespace Tema_2_1
{
    class Program
    {
        static void Description()
        {
            Console.WriteLine("\n Заданы три функции y1=x^3, y2=x^3+1, y3= 1/(1+x^2)." +
                "\n Определить, являются ли эти функции четными или нечетными. \n");
        }
        static byte Chet_nechet(byte i)
        {
            byte x, chet = 0, nechet = 0, result;
            double y, y1;
            if (i == 0)
                for (x = 1; x < 10; x++)
                {
                    y = Math.Pow(x, 3);
                    y1 = Math.Pow(-x, 3);
                    Console.WriteLine($" x =  {x,2}\ty = {y}\n x =  -{x,1}\ty = {y1}");
                    if (y == y1) ++chet;
                    else if (y == -y1) ++nechet;
                    else break;
                }
            if (i == 1)
                for (x = 1; x < 10; x++)
                {
                    y = Math.Pow(x, 3) + 1;
                    y1 = Math.Pow(-x, 3) + 1;
                    Console.WriteLine($" x =  {x,2}\ty = {y}\n x =  -{x,1}\ty = {y1}");
                    if (y == y1) ++chet;
                    else if (y == -y1) ++nechet;
                    else break;
                }
            if (i == 2)
                for (x = 1; x < 10; x++)
                {
                    y = 1 / (1 + Math.Pow(x, 2));
                    y1 = 1 / (1 + Math.Pow(-x, 2));
                    Console.WriteLine($" x =  {x,2}\ty = {y}\n x =  -{x,1}\ty = {y1}");
                    if (y == y1) ++chet;
                    else if (y == -y1) ++nechet;
                    else break;
                }
            if (chet == 9) result = 0;
            else if (nechet == 9) result = 1;
            else result = 2;
            return result;
        }
        static void Main(string[] args)
        {
            Description();
            string[] str = { "y1=x^3", "y2=x^3+1", "y3=1/(1+x^2)" };
            for (byte i = 0; i < 3; i++)
            {
                byte result = Chet_nechet(i);
                if (result == 0) Console.WriteLine($"\n Функция {str[i]} четная.\n");
                else if (result == 1) Console.WriteLine($"\n Функция {str[i]} нечетная.\n");
                else Console.WriteLine($"\n Функция {str[i]} не является ни четной, ни нечетной!\n");
            }
            Console.ReadKey();
        }
    }
}

Тут в функции Chet_nechet в каждом if выполняются одни и те же операции:

Console.WriteLine($" x = {x,2}\ty = {y}\n x = -{x,1}\ty = {y1}");
if (y == y1) ++chet;
else if (y == -y1) ++nechet;
else break;

Как сделать отдельную функцию для этих операций?
  • Вопрос задан
  • 468 просмотров
Решения вопроса 1
FoggyFinder
@FoggyFinder
Попробуйте рассматривать функцию в программировании как некоторый участок кода который выполняет определенное действие.

Давайте разберем на примере вашего задания:

Заданы три функции y1=x^3, y2=x^3+1, y3= 1/(1+x^2). Определить, являются ли эти функции четными или нечетными.


Вас может смущать число "три" в формулировке, отбросьте его как не существенное, тогда будет проще понять как правильно поступить. Переформулируем, оставив только самую суть:

Определить четность функций.


Возьмем определение "четности":

Нечётными и чётными называются функции, обладающие симметрией относительно изменения знака аргумента.


Так как функция может быть произвольная, то можно лишь говорить о свойствах на некотором интервале с заданным шагом.

Определим тип функции в виде перечисления:

public enum FuncType { Odd, Even, Unknown };

Нам понадобиться функция которая будет определять тип функции для конкретной точки:

Func<double, FuncType> isEven = v =>
{
    var y1 = func(v);
    var y2 = func(-v);

    if (y1 == y2)
        return FuncType.Even;
    if (y1 == -y2)
        return FuncType.Odd;

    return FuncType.Unknown;
};


и функция для суммирования двух состояний:

Func<FuncType, FuncType, FuncType> add = (v1, v2) =>
{
    if (v1 == v2) return v2;
    return FuncType.Unknown;
};


теперь, чтобы не делать ненужные проверки, нужен способ вернуть результат сразу как только станет понятно, что функция не является ни четной ни нечетной:

Для начала нужно определить "состояние" функции для первой точки (a) и, если, однозначного ответа нет, то можно возвращать результат - в дальнейших вычислениях нет необходимости:

var funcType = isEven(a);
if (funcType == FuncType.Unknown)
    return FuncType.Unknown;


теперь, когда предварительная обработка сделана, можно писать цикл:

for (double x = a + step; x <= b; x += step)
    {
        var funcTypeNext = isEven(x);
        funcType = add(funcType, funcTypeNext);
        if (funcType == FuncType.Unknown)
            return FuncType.Unknown;
     }


и в итоге нужно вернуть funcType.

Полностью функция выглядит так:

public static FuncType IsEvenFunction(Func<double, double> func, double a, double b, double step)
{

    Func<double, FuncType> isEven = v =>
    {
        var y1 = func(v);
        var y2 = func(-v);

        if (y1 == y2)
            return FuncType.Even;
        if (y1 == -y2)
            return FuncType.Odd;

        return FuncType.Unknown;
    };

    Func<FuncType, FuncType, FuncType> add = (v1, v2) =>
    {
        if (v1 == v2) return v2;
        return FuncType.Unknown;
    };

    var funcType = isEven(a);
    if (funcType == FuncType.Unknown)
        return FuncType.Unknown;

    for (double x = a + step; x <= b; x += step)
    {
        var funcTypeNext = isEven(x);
        funcType = add(funcType, funcTypeNext);
        if (funcType == FuncType.Unknown)
            return FuncType.Unknown;
    }

    return funcType;
}


Проверка:

Func<double, double> fn1 = x => x * x * x;
Func<double, double> fn2 = x => x * x * x + 1;
Func<double, double> fn3 = x => 1 / (1 + x * x);

Console.WriteLine("Fn1: {0}", IsEvenFunction(fn1, 1, 10, 0.01));
Console.WriteLine("Fn2: {0}", IsEvenFunction(fn2, 1, 10, 0.01));
Console.WriteLine("Fn3: {0}", IsEvenFunction(fn3, 1, 10, 0.01));


Теперь что касается вывода как у вас примере, попробуйте добавить функцию .ToString() для форматирования перечисления. А также добавить описание для функции. Можно использовать кортеж - (описание, функция).

Если возникнут вопросы - не стесняйтесь спрашивать, буду рад помочь.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
MrMureno
@MrMureno
VR for all
Вы не поверите, но просто взять и сделать отдельным методом/функцией))

параметры для функции определить не можете?? ..разбирайте тогда примеры попроще, учитесь. разве не для этого такие задания/лабораторные работы делают
Ответ написан
profesor08
@profesor08
Ну вот тебе дали три функции, тебе их надо проверить на четность. Гуглишь что такое четные и нечетные функции. Далее пишешь некий код, который это проверяет. Для каждой функции пишешь функцию, потом сверяешь результаты их выполнения. Потом останется проверить результаты на множестве цифр (массив), если проверка для каждого значение вернет один и тот-же результат, тогда можно делать выводы что это за функция, четная или нет, если результаты разные, то ни та ни другая.

public class Program
    {
        
        delegate double Fn(double x);
        
        static int Check(Fn f, double x) {
            if ( f(x) == f(-x) ) {
                return 1;
            }
            else if ( f(-x) == -f(x) ) {
                return -1;
            }
            else {
                return 0;
            }
        }
        
        static string Result(string name, int result) {
            switch (result) {
                case 1: return name + "четная";
                case 0: return name + "никакая";
                case -1: return name + "не четная";
            }
            
            return name + "unknown result";
        }
        
        public static void Main(string[] args)
        {
            double num = 6.0;
            
            Fn fn1 = x => x * x * x;
            Fn fn2 = x => x * x * x + 1;
            Fn fn3 = x => 1 / (1 + x * x);
            
            Console.WriteLine(Result("Fn1: ", Check(fn1, num)));
            Console.WriteLine(Result("Fn2: ", Check(fn2, num)));
            Console.WriteLine(Result("Fn3: ", Check(fn3, num)));
        }
    }
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы