Horner Rekurencyjnie

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Proszę o pomoc odnośnie poprawienia kodu bo już sam nie wiem jak go naprawić :/

Z góry bardzo dziękuje...

Kopiuj
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Consola_Horner_Rekurencyjnie
{
    class Program
    {
        static void Main(string[] args)

        {
            int n;

            Console.WriteLine("Podaj stopień wielomioanu: ");
            n = Convert.ToInt32(Console.ReadLine());

            int[] a = new int[n];

            Console.WriteLine("Podaj wartosc a: ");

            for (int i = 0; i <= n; i++)
            {
                Console.WriteLine("a [" + i);
                a[i] = Convert.ToInt32(Console.ReadLine());
            }

            int x;

            Console.WriteLine("Podaj x:");
            x = Convert.ToInt32(Console.ReadLine());

            int Horner(int i)
                {
                    if (i == 0)
                        return a[0];
                    else
                        return Horner(i - 1) * x + a[i];
                }

            Console.WriteLine("Wynik to:" + Horner);
        }
   
    }
}
Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
0

Od kiedy można deklarować funkcje w funkcji?
Poza tym błędnie wywołujesz funkcję (nie podajesz parametrów).

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Próbowałem to przerobić z kodu w C++ oryginał wygląda tak:

Kopiuj
 
int Horner;
int n;
int *a = new int[n];
int x;


int main()
{
        
        cout <<"Podaj stopień wielomianu: ";
        cin >> n;
        cin.ignore();


        cout << "Podaj wartość a: \n";
        for (int i = 0; i <= n; i++)
        {
           cout <<"a[" <<i<<"] = ";
           cin >> a[i];
           cin.ignore();
        }

        cout <<"Podaj x: ";
        cin >> x;
        cin.ignore();

        cout <<"Wynik to: " << Horner(n);
        
        getchar ();
        return 0;
}

int Horner (int i)
{
        if (i == 0)
           return a[0];
        else 
           return Horner (i - 1) * x + a[i];
}

Starałem się właśnie przerobić ten kod na C#

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Poprawiłem kod na taki jak w C++ domyślam się że dosłownie taki nie będzie to co umiałem to przerobiłem na C# ale dalej już nie za zbytnio mi idzie...

Prosił bym was o pomoc bo dalej sobie nie radzę...

Kopiuj
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Consola_Horner_Rekurencyjnie
{
    class Program
    {
        int Horner;
        int n;
        int[] a = new int[n];
        int x;

        static void Main(string[] args)

        {
            Console.WriteLine("Podaj stopień wielomioanu: ");
            n = Convert.ToInt32(Console.ReadLine());


            Console.WriteLine("Podaj wartosc a: ");

            for (int i = 0; i <= n; i++)
            {
                Console.WriteLine("a [" + i);
                a[i] = Convert.ToInt32(Console.ReadLine());
            }

            Console.WriteLine("Podaj x:");
            x = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Wynik to:" + Horner(n));
        }

        int Horner (int i)
        {
            if (i == 0)
                return a[0];
            else
                return Horner(i - 1) * x + a[i];
        }
    }
}
 
MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Takie błędy mi pokazuje:

Error 2 A field initializer cannot reference the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.n'

Error 5 An object reference is required for the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.a'

Error 8 An object reference is required for the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.Horner(int)'

Error 3 An object reference is required for the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.n'

Error 4 An object reference is required for the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.n'

Error 7 An object reference is required for the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.n'

Error 6 An object reference is required for the non-static field, method, or property 'Consola_Horner_Rekurencyjnie.Program.x'

Error 1 The type 'Consola_Horner_Rekurencyjnie.Program' already contains a definition for 'Horner'

siararadek
  • Rejestracja: dni
  • Ostatnio: dni
0

To nie łaska wpisać błąd na google? Przecież jasno pisze, że z statycznego main nie masz dostępu do zmiennych instancji klasy. A ostatni błąd to bodajże przez posiadanie pola i funkcji Horner.

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Poprawiłem trochę ten kod ale pokazuje mi błąd przy instrukcji "if" nie wiem jak to poprawić bo pisze że "i" nie istnieje...

Error 2 Since 'Consola_Horner_Rekurencyjnie.Program.Main(string[])' returns void, a return keyword must not be followed by an object expression
Error 1 The name 'i' does not exist in the current context

Kopiuj
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Consola_Horner_Rekurencyjnie
{
    class Program
    {

        static void Main(string[] args)

        {

            int n;

            Console.WriteLine("Podaj stopień wielomioanu: ");
            n = Convert.ToInt32(Console.ReadLine());

            int[] a = new int[n];

            Console.WriteLine("Podaj wartosc a: ");

            for (int i = 0; i <= n; i++)
            {
                Console.WriteLine("a [" + i);
                a[i] = Convert.ToInt32(Console.ReadLine());
            }

            int x;

            Console.WriteLine("Podaj x:");
            x = Convert.ToInt32(Console.ReadLine());

            int Horner;
         
            if (i == 0)
            {
                return a[0];
            }
            else 
            {
                return Horner = (i - 1) * x + a[i];
            }

            Console.WriteLine("Wynik to:" + Horner);
            Console.ReadLine();
        }
    }
}
 
MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Pytanie czy coś w tym stylu może być ?

Kopiuj
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Consola_Horner_Rekurencyjnie
{
    class Program
    {

        static void Main(string[] args)

        {
            int Horner;
            int x;
            int n;

            Console.WriteLine("Podaj stopień wielomioanu: ");
            n = Convert.ToInt32(Console.ReadLine());

            int[] a = new int[n];

            Console.WriteLine("Podaj wartosc a: ");

            for (int i = 0; i <= n; i++)
            {
                Console.WriteLine("a [" + i);
                a[i] = Convert.ToInt32(Console.ReadLine());

                if (i <= 0)
                {
                    return a[0];
                }
                else
                {
                    return Horner = (i - 1) * x + a[i];
                }
            }            

            Console.WriteLine("Podaj x:");
            x = Convert.ToInt32(Console.ReadLine());    

            Console.WriteLine("Wynik to:" + Horner);
            Console.ReadLine();
        }
    }
}

Tylko jeszcze

Kopiuj
 return 

pokazuje mi że jest w formie "Void" i nie może zwrócić wartości wiecie może jak to zmienić ?

Bo jak przerabiam

Kopiuj
 static void Main(string[] args) 

na int to już mi się wszystko wywala...

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Tylko teraz lokalnie nie mam zadeklarowanego "Horner" i "x" próbowałem to przenieść w różne miejsca w kodzie i nic nie pomaga :/

RE
  • Rejestracja: dni
  • Ostatnio: dni
2

w C# też są lambdy, ale już się tak wygodnie tego zrobić nie da.

Kopiuj
Func<int, int> horner = null;
horner = i => i == 0 ? a[0] : horner(i - 1) * x + a[i];
MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Poprawiłem kod źródłowy, C# nie pokazuje żadnych błędów...

Ale wynik niestety nie jest taki jak się spodziewałem, po tekście "Wynik to: " pokazuje następujący tekst "System.Func '2[System.Int32,System.Int32]

Kopiuj
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Consola_Horner_Rekurencyjnie
{
    class Program
    {

        static void Main(string[] args)

        {
                        
            int n;

            Console.WriteLine("Podaj stopień wielomioanu: ");
            n = Convert.ToInt32(Console.ReadLine());

            int[] a = new int[++n];

            Console.WriteLine("Podaj wartosc a: ");
           
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("a [" + i + "] = ");
                a[i] = Convert.ToInt32(Console.ReadLine());
            }
            
            int x;

            Console.WriteLine("Podaj x:");
            x = Convert.ToInt32(Console.ReadLine());
            

            Func<int, int> Horner = null;
            Horner = (i) => (i == 0) ? a[0] : Horner(i - 1) * x + a[i];              

            Console.WriteLine("Wynik to:" + Horner);
            Console.ReadLine();
        }
    }
}
siararadek
  • Rejestracja: dni
  • Ostatnio: dni
0

Rev po jakiego diabła dałeś mu Func, jak on nie wie jak go wykorzystać?

mcshow - w twoim przypadku zamiast samo Horner, powinno być Horner(x) w Console.WriteLine. Ale zaraz jak to poprawisz, masz się wziąć za książkę z .NET. Takie błędy jakie tutaj popełniasz mógłbyś zaraz rozwiązać, gdybyś miał choć elementarne podstawy.

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Mam jeszcze jedno pytanie gdyż mam już takową postać kodu która czysto teoretycznie powinna zwracać odpowiedni wynik ale...

wyskakuje mi błąd że zmienna "x" jest już wcześniej zadeklarowana (co musiałem uczynić żeby uzyskać ją od użytkownika) a wymieniona w "Horner" na inne znaczenie...

jak zmieniam "x" w "Horner" na np. "y" to nie pokazuje mi żadnych błędów ale po uruchomieniu program mi się wywala całkowicie ( i w sumie to rozumiem bo wymagam od użytkownika podania wartości X i na niej ma być wykonywane działanie a nie na "y")

Jak zmienić nazwę dla "x" tak żeby nie wyskakiwał błąd...?

Kopiuj
 
Func<int, int, int> Horner = null;
Horner = (i, x) => (i == 0) ? a[0] : Horner(i - 1, x) * x + a[i];

int wynik = Horner(n, x);
RE
  • Rejestracja: dni
  • Ostatnio: dni
0

Po to mądrzy ludzie wymyślili domknięcia, żebyś mógł w tej funkcji odwołać się do x bez przekazywania go w dodatkowym argumencie. Zostaw kod w takiej postaci, w której ja go napisałem.

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

To czysto teoretycznie powinno być dobrze... a program powinien się kompilować...

Kopiuj
 
        {
            
            int n;

            Console.WriteLine("Podaj stopień wielomioanu: ");
            n = Convert.ToInt32(Console.ReadLine());

            int[] a = new int[++n];

            Console.WriteLine("Podaj wartosc a: ");

            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("a [" + i + "] = ");
                a[i] = Convert.ToInt32(Console.ReadLine());
            }

            int x;

            Console.WriteLine("Podaj x:");
            x = Convert.ToInt32(Console.ReadLine());

            Func<int, int, int> Horner = null;
            Horner = (i, x) => (i == 0) ? a[0] : Horner(i - 1, x) * x + a[i];

            int wynik = Horner(n, x);

            Console.WriteLine("Wynik to:" + wynik);
            Console.ReadLine();
        }
    }
}
Szarp
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 48
0
Kopiuj
Horner = (i, x) => (i == 0) ? a[0] : Horner(i - 1, x) * x + a[i];

Nie możesz tutaj użyć nazwy x - używasz już takiej zmiennej w programie.
Zmień x na np. z.
Następnym razem podaj, gdzie i jaki wywala ci błąd.

RE
  • Rejestracja: dni
  • Ostatnio: dni
0

Żadna zmiana x na z czy cokolwiek innego. Na tym polega domknięcie w tym miejscu, że w funkcji lambda możesz sobie wykorzystać to x, które zadeklarowałeś wcześniej, po za tą faktyczną funkcją. Nie trzeba go w argumencie przekazywać.

Drugi błąd to zmiana wymiaru wielomianu - w pewnym momencie zwiększasz go o 1 i taki nieprawidłowy wymiar przekazujesz do funkcji.

Zostaw funkcję taką, którą ci podałem, nic w niej nie zmieniaj. Tylko to n popraw.

Sarrus
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2512
0

@mcshow Tak z ciekawości, do czego potrzebujesz ten program?

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Wielomian zwiększam o jeden bo ma być od 0 do n... A w podanym poniżej miejscu zmniejszam go i tylko dlatego bo inaczej kod się nie kompiluje:

Kopiuj
 
for (int i = 0; i < n; i++)
            {
                Console.WriteLine("a [" + i + "] = ");
                a[i] = Convert.ToInt32(Console.ReadLine());
            }

Więc wydaje mi się że mam dobrze...

@Rev co do twojego kodu który podałeś to wszystko ok, nie wyskakuje żaden błąd ale dostaje złe wyniki...

Kopiuj
 
Func<int, int> horner = null;
horner = i => i == 0 ? a[0] : horner(i - 1) * x + a[i];
MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Dobra poddaje się... :/

Pytanie czy da się ten kod:

Kopiuj
 
Func<int, int> horner = null;
            horner = i => i == 0 ? a[0] : horner(i - 1) * x + a[i];

przedstawić w jakiejś prostszej postaci jak np. ???

Kopiuj
 
int w;

            w = a[0];
            for (int i = 1; i < n; i++)
            {
                w = w * x + a[i];
            }
MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Co myślicie o tym... Ma to rację bytu ?

Kopiuj
 
public double Horner(double[] a, double x)
{
 	int n = a.lenght;
	double wynik = a[n];
	for (int i = n-1; i >= 0;i--)
	{
		wynik = wynik * x + a[i];
	}
	return wynik;
}
Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0
Rev napisał(a)

Ja to uznaje za plus, z reszta, gdyby tak nie bylo nigdy domkniecia by nie byly feature jezyka

Ale pytanie było o funkcje lokalne. W C można bezpośrednio:

Kopiuj
int foo()
{
    int a = 3;

    int abc(int b, int c)
    {
        return a+b+c;
    }

    return abc(4,7);
}

w C++ można z powodzeniem zastosować wyrażenie lambda, jest tylko „trudniejsza” składnia — ale przecież C++ lubi wszystko utrudniać:

Kopiuj
int foo()
{
    int a = 3;

    auto abc = [&](int b, int c) -> int
    {
        return a+b+c;
    };

    return abc(4,7);
}

Co ciekawe, kolejnością poszczególnych elementów zbliża to C++ do Pascala (typ zwracany funkcji na końcu za parametrami).

w C# bezpośrednim odpowiednikiem byłoby:

Kopiuj
static int foo()
{
    int a = 3;

    var abc = (int b, int c) =>
    {
        return a+b+c;
    };

    return abc(4,7);
}

ale raz że nie można podać jawnie zwracanego typu, to jeszcze kompilator nie potrafi się „domyśleć” jaki ma być typ zmiennej abc (a w C++ jakoś może...)

Nic nie da składnia ze słowem delegate:

Kopiuj
static int foo()
{
    int a = 3;

    var abc = delegate (int b, int c)
    {
        return a+b+c;
    };

    return abc(4,7);
}

To samo; nie może być var.

Trzeba podać jawnie typ:

Kopiuj
static int foo()
{
    int a = 3;

    System.Func<int,int,int> abc = (int b, int c) =>
    {
        return a+b+c;
    };

    return abc(4,7);
}

ale teraz dwukrotnie powtarzamy typy parametrów. możemy jedne wyrzucić:

Kopiuj
static int foo()
{
    int a = 3;

    System.Func<int,int,int> abc = (b, c) =>
    {
        return a+b+c;
    };

    return abc(4,7);
}

I to jest jak w twoim przykładzie. Niestety, typy parametrów i ich nazwy są rozdzielone, i nie widać który jest który (a gdyby parametrów było więcej?). Przypominam, że chodzi nam po prostu o symulowanie funkcji lokalnej.
Na dodatek nie jest oczywiste, które dwa z trzech intów to typy parametrów, a który to typ zwracany. Przyznam że nawet nie wiem, zawsze muszę to w helpie sprawdzać.

Wniosek 1: lambdy w C# do udawania funkcji lokalnych się nie nadają.
To działa, ale składnia jest do kitu, gorsza niż C++.

Wniosek 2: C++ i C# powinny po prostu pozwalać na funkcje lokalne, choćby tylko jako lukier składniowy na odpowiednie lambdy. Nie widzę przeciwskazań, skoro i tak można to osiągnąć na około.

MC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

I tu też moje pytanie jak by można najprościej przedstawić kod z C++

Kopiuj
 
int Horner (int i)
{
        if (i == 0)
           return a[0];
        else 
           return Horner (i - 1) * x + a[i];
}

w C#... bez domknięć, Func itp... ? Musi być taki jak wyżej podany bo chcę pokazać różnicę w sposobie liczenia między Intracyjnym a Rekurencyjnym...

Endrju
  • Rejestracja: dni
  • Ostatnio: dni
0

W C można bezpośrednio

W C nie ma funkcji zagnieżdżonych!

somekind
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
0
Azarien napisał(a)

Na dodatek nie jest oczywiste, które dwa z trzech intów to typy parametrów, a który to typ zwracany. Przyznam że nawet nie wiem, zawsze muszę to w helpie sprawdzać.

OSTATNI to typ zwracany. To jest ekstremalnie łatwe do zapamiętania.

Wniosek 1: lambdy w C# do udawania funkcji lokalnych się nie nadają.
To działa, ale składnia jest do kitu, gorsza niż C++.

Nadają się i to całkiem dobrze. Może i pisanie Func<T1, T2, ..., TOut> może nie jest do końca wygodne, za to od razu widać, co funkcja przyjmuje i co zwraca. Szczerze mówiąc, wolę chyba taką formę zapisu niż miałoby to być var, które nie daje żadnej informacji o typach podczas czytania kodu.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.