Algoritmus pre posun po osi   zodpovězená otázka

C#, VB.NET

Mám taký problém a už dlhšie si s ním neviem poradiť. Pomôže mi niekto prosím? Ide skôr o logiku.

Mám premenné s hodnotami:

X(0)= -2

X(1)= -1

X(2)= 0

X(3)= 1

X(4)= 2

X(5)= 3

X(6)= 4

Pole hodnôt je obmedzené zhora aj zdola. X(i) > -2 a x<=4,5. rodiel medzi dvoma hodnotami je 1. V prípade, že X() prekročí hranicu, presúva sa dole alebo hore

Napríklad si určím, že X(5) = -0,5

Tak všetky hodnoty budú:

X(0)= 1,5

X(1)= 2,5

X(2)= 3,5

X(3)= 4,5

X(4)= -1,5

X(5)= -0,5

X(6)= 0,5

Alebo do algoritmu zadám X(2) = 4,3

Tak všetky hodnoty budú:

X(0)= 2,3

X(1)= 3,3

X(2)= 4,3

X(3)= -1,7

X(4)= -0,7

X(5)= 0,3

X(6)= 1,3

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zrovna to podivné pořadí prvků pole bude důležité, že? ;)

Nebo může být výsledek vždy seřazený od nejmenšího po největší?

Ve smyslu, ať zadám -0,5 nebo 0.5 nebo 1,5 nebo 4,5 ... ,

tak jen vrátí všechny hodnoty v daném limitu x > -2 a x <= 4.5

X(0)= -1,5

X(1)= -0,5

X(2)= 0,5

X(3)= 1,5

X(4)= 2,5

X(5)= 3,5

X(6)= 4,5

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ďakujem ale takto nie.

Zadám pre niektoré X(n), ktorých počet je stále rovnaký(7), ľubovoľnú hodnotu na osi x v stanovených hraniciach (-2,4.5> a potom k nemu priraďujem zľava X(n-1) = X(n) -1, X(n-2) = X(n-1)-1... pokiaľ je X() > 2 ak bude X(n-k) <=2 preskočí na pravú stranu od X(n)a znova sa zmenšuje o 1. V skutočnosti je to niečo ako ciferník na hodinách, len čísla sú iné ( 7 číslic, pričom -2 je 24:00). Hociktoré X(n) položíme do ciferníka a ostatné X() sú v poradí rovnomerne rozložené po ciferníku. Keby som to nakreslil bolo by to jasnejšie.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkusmo, aby mi funkce vrátila pole požadovaných hodnot :

Dim decimals1 As Decimal() = LimitedValues(5, -0.5D)
Dim decimals2 As Decimal() = LimitedValues(2, 4.3D)

    Function LimitedValues(ByVal ElementPosition As Integer, ByVal ElementValue As Decimal) As Decimal()
        Dim al As New List(Of Decimal)
        Dim MinValue As Decimal = -2
        Dim MaxValue As Decimal = 4.5

        If ElementValue > MinValue And ElementValue <= MaxValue Then
            al.Add(ElementValue)
            While al(0) - 1 > MinValue
                al.Insert(0, al(0) - 1)
            End While
            While al(al.Count - 1) + 1 <= MaxValue
                al.Add(al(al.Count - 1) + 1)
            End While
            Dim arr As Decimal() = al.ToArray

            Dim j As Integer = ElementPosition
            Dim k As Integer = al.IndexOf(ElementValue)
            If k <> j Then
                Dim ps As Integer() = Enumerable.Range(0, al.Count).ToArray
                Dim i As Integer = 0
                Do
                    ps(j) = k
                    j = IIf(j < ps.GetUpperBound(0), j + 1, 0)
                    k = IIf(k < ps.GetUpperBound(0), k + 1, 0)
                    i += 1
                Loop While i < ps.Length
                For i = ps.GetLowerBound(0) To ps.GetUpperBound(0)
                    arr(i) = al(ps(i))
                Next
            End If
            Return arr
        End If

        Return al.ToArray
    End Function

Žádnou logiku jsem nenašel.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Pokúšam sa to prepísať do C# a IIf je pre mňa v tomto smere úplny koniec. Toto je jasná logika:-)

Už je to v poriadku. Ďakujem.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ještě jeden pokus to rovnou číslovat v novém pořadí :

Dim axisdecimals1 As Decimal() = AxisValuesLimited(5, -0.5D)
Dim axisdecimals2 As Decimal() = AxisValuesLimited(2, 4.3D)

    Function AxisValuesLimited(ByVal ElementPosition As Integer, ByVal ElementValue As Decimal) As Decimal()
        Dim MinValue As Decimal = -2
        Dim MaxValue As Decimal = 4.5
        Dim lkvp As New List(Of KeyValuePair(Of Integer, Decimal))
        If ElementValue > MinValue And ElementValue <= MaxValue Then
            lkvp.Add(New KeyValuePair(Of Integer, Decimal)(ElementPosition, ElementValue))
            While lkvp(0).Value - 1 > MinValue
                lkvp.Insert(0, New KeyValuePair(Of Integer, Decimal)(IIf(lkvp(0).Key > 0, lkvp(0).Key - 1, 6), lkvp(0).Value - 1))
            End While
            While lkvp(lkvp.Count - 1).Value + 1 <= MaxValue
                lkvp.Add(New KeyValuePair(Of Integer, Decimal)(IIf(lkvp(lkvp.Count - 1).Key < 6, lkvp(lkvp.Count - 1).Key + 1, 0), lkvp(lkvp.Count - 1).Value + 1))
            End While
        End If
        Return (From kvp As KeyValuePair(Of Integer, Decimal) In lkvp Order By kvp.Key Select kvp.Value).ToArray
    End Function
nahlásit spamnahlásit spam 0 odpovědětodpovědět

... a ještě chybové stavy :

není nijak pořešeno a ověřeno, zda-li je ElementPosition v daném rozsahu (0-6)

není-li ElementValue v daném limitu, pak vrátí prázdné pole nulové délky

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Základ bol dobrý a ako nakopnutie mi to stačilo. Urobil som to trošku primitivnejšie, ale funguje to. Určím si prvu hodnotu, od ktorej potom postupujem najprv doprava a potom doľava a súčasne kontrolujem index aj hodnotu (toto vlastne bol Váš nápad)a pri hraničných stavoch mením hodnotu alebo index, podľa toho, ktorá zmena skôr príde. Nemôžem okopírovať kód lebo ten je o vykresľovaní a momentálne ho mám rozhádzaný.

Ďakujem za pomoc.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zdravím,

možná jdu s křížem po funuse, ale zkuste to takhle

        static void Main(string[] args)
        {
            var val = 4.3;
            var index = 2;

            foreach (var item in LimitValues(val, index))
            {
                Console.WriteLine(item);
            }

            val = -0.5;
            index = 5;

            Console.WriteLine();

            foreach (var item in LimitValues(val, index))
            {
                Console.WriteLine(item);
            }
        }

        public static double[] LimitValues(double inputValue, int index)
        {
            const double lowerBound = -2;
            const double upperBound = 4.5;
            const int outputArrayLength = 7;

            if (index >= outputArrayLength || index < 0)
                throw new ArgumentOutOfRangeException(nameof(index));

            if(inputValue <= lowerBound || inputValue > upperBound)
                throw new ArgumentOutOfRangeException(nameof(inputValue));

            var outputArray = new double[outputArrayLength];

            for (int i = outputArrayLength; i > 0; i--)
            {
                var currentIndex = (i + index + outputArrayLength) % outputArrayLength;
                outputArray[currentIndex] = inputValue;
                inputValue -= 1;

                if (inputValue < lowerBound)
                {
                    inputValue = upperBound;
                }
            }


            return outputArray;
        }

R.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ještě oprava :)

      if (inputValue <= lowerBound)
      {
          inputValue = upperBound;
      }

R.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Skoro presne takto som to urobil aj ja. Ďakujem za odpoveď. Pekný deň prajem.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak se potom pochlubte svým řešením :)

R.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback