Válí se ti projekty v šuplíku? Dostaň je mezi lidi a získej cool tričko a body na profi IT kurzy v soutěži ITnetwork summer 2017!
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

Diskuze: Jak otočit slovo?

C# .NET .NET (C# a Visual Basic) Jak otočit slovo? American English version English version

Aktivity (1)
Avatar
michaelbeats7:14.3.2015 20:07

Mám jeden textbox , jeden button a jeden label.. když napišu do textboxu napřiklad "Pes"a zmačknu button tak se v labelu objeví "seP" .. jak na to?

 
Odpovědět 14.3.2015 20:07
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na michaelbeats7
Jan Vargovský:14.3.2015 20:13
label.Text = new string(textbox.Text.Reverse().ToArray());
Akceptované řešení
+20 Zkušeností
Řešení problému
 
Nahoru Odpovědět 14.3.2015 20:13
Avatar
Odpovídá na Jan Vargovský
michaelbeats7:14.3.2015 20:20

Diky moc.. šlo by to napsat ve více kodech abych to pochopil?:)

 
Nahoru Odpovědět 14.3.2015 20:20
Avatar
Odpovídá na michaelbeats7
Petr Čech (czubehead):14.3.2015 20:42

To je součást frameworku, na tom se nedá moc co vysvětlovat

Nahoru Odpovědět 14.3.2015 20:42
Why so serious? -Joker
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na michaelbeats7
Jan Vargovský:14.3.2015 20:49

Vezmeš string, reverzneš ho, převedeš na pole, vytvoříš instanci.

Nauč se základní konstrukce programování, pak se nebudeš muset ptát.

 
Nahoru Odpovědět 14.3.2015 20:49
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:14.3.2015 21:33

Problém je, že ty jsi "nereverznul" string. Kdyby ano, nemusel bys výsledek pak převádět na pole. Ve skutečnosti jsi vytvořil enumerátor pro typ char, kterýs pak převedl na pole typu char a to pak vložil do konstruktoru stringu.

Rozepsaně je to takto, snad to pomůže michaelbeats7

string retezec = "Test pro převrácení.";
IEnumerable<char> enumerator = retezec.Reverse();
char[] pole = enumerator.ToArray();
string prevracenyretezec = new string(pole);
Console.WriteLine(prevracenyretezec);
 
Nahoru Odpovědět  +1 14.3.2015 21:33
Avatar
Michal Žůrek (misaz):14.3.2015 21:41

Hoši, co kdybyste mu to ukázali i s tím cyklem? Ano lze to krásně napsat na jeden řádek, ale v rámci algoritmizace je možná dobré si to aspoň zkusit. Navíc nezapomeňte, že metoda Reverse je taky napsaná v C#, přemýšleli jste nad tím, jak funguje?

string input = "Pes";
string output = ""; // vytvoříme si proměnnou kam budeme řpidávat písmena

// obrácený cykl, i bude nejprve 2, pak 1, 0 a u -1 už podmínka neprojde
for (int i = input.Length - 1; i >= 0; i--) {
    output += input[i]; // přilepíme aktuální procházené písmeno do výsledku
}

Console.WriteLine(output);
Nahoru Odpovědět 14.3.2015 21:41
Nesnáším {}, proto se jim vyhýbám.
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
hanpari:14.3.2015 21:56

Klidně to sem napiš, rád se nechám poučit.

 
Nahoru Odpovědět 14.3.2015 21:56
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na hanpari
Jan Vargovský:14.3.2015 22:10

Ve skutečnosti se udělalo interně tohle:

string text = "Pes";
char[] pole = text.ToCharArray();
Array.Reverse(pole, 0, pole.Length);
string novyText = new string(pole);

A to se zase dá převést ještě o úroveň níže:

string text = "Pes";
char[] pole = text.ToCharArray();
int i = 0, j = pole.Length - 1;
while (i < j)
{
    char tmp = pole[i];
    pole[i] = pole[j];
    pole[j] = tmp;
    i++;
    j--;
}
string novyText = new string(pole);
Editováno 14.3.2015 22:12
 
Nahoru Odpovědět 14.3.2015 22:10
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
Jan Vargovský:14.3.2015 22:10

Ale fuj, takové věci ho radši neuč :)

 
Nahoru Odpovědět  +1 14.3.2015 22:10
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:14.3.2015 22:19

To si nemyslím. Nebudu se tvářit jako velký expert na C# a potažmo LINQ, ale takto to nefunguje. Tak, jak jsi to napsal, jsi vynechal to podstatné, totiž líné vyhodnocení "deferred execution" metody Reverse, ostatně víc je tady včetně reimpletace metody:

https://edulinq.googlecode.com/…Reverse.html

Editováno 14.3.2015 22:20
 
Nahoru Odpovědět 14.3.2015 22:19
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na hanpari
Jan Vargovský:15.3.2015 0:00

Jo, já se koukal na reverse u listu.

Deferred execution v tomto případě nemá žádnou roli :) jinak jo, ta implementace v tom linku je celkem přesná.

Každopádně jsem si napsal malý benchmark, kódy seřazeny od nejrychlejšího:

1. Samostatně naimplementovaný reverse

string text = "as5d4as6d5";
char[] pole = text.ToCharArray();
int i = 0, j = pole.Length - 1;
while (i < j)
{
    char tmp = pole[i];
    pole[i] = pole[j];
    pole[j] = tmp;
    i++;
    j--;
}
string novyText = new string(pole);

2. Pomocí reverse metody na Array třídě

string text = "as5d4as6d5";
var arr = text.ToCharArray();
Array.Reverse(arr);
string novyText = new string(arr);

3. Pomocí reverse metody na List<T>

string text = "as5d4as6d5";
var tmp = text.ToCharArray().ToList();
tmp.Reverse();
string novyText = new string(tmp.ToArray());

4. pomocí reverse metody na IEnumerable<T>

string text = "as5d4as6d5";
string novyText = new string(text.Reverse().ToArray());

Pozn. ta 3 a 4 se dost blbě měří, jednou vyjde poměr časů 1:10 a potom zase 10:1 :D

 
Nahoru Odpovědět  +1 15.3.2015 0:00
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:15.3.2015 6:16

Souhlasím, že v tomto konkrétním případě to význam nemá, když uvážím, že enumerátor napřed musí udělat pole a pak teprve nový string. Ale to záleží, jak je to v c# naimplementované.

Ten benchmark jsi podle mne nenapsal vhodně. Abys to lépe porovnal, měl bys zkusit obracet extrémně dlouhé řetězce. Na řetězce, co má 10 znaků nic nezměříš. Jestli se ti chce, zkus dosadit do svého benchmarku toto s hodnotou end povězme třeba 20 000.

public static string CreateString(int end)
{
        var r = new Random();
        string newstr = "";
        for (int i = 0; i < end; i++)
        {
                newstr += Char.ConvertFromUtf32(r.Next(65, 122));
        }
        return newstr;
}
 
Nahoru Odpovědět  +1 15.3.2015 6:16
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na hanpari
Jan Vargovský:15.3.2015 13:16

V podstatě stejné výsledky, ale Array.Reverse tam volá interně něco rychlejšího pro zpřeházení paměti, takže je to o pár % rychlejší.

 
Nahoru Odpovědět 15.3.2015 13:16
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:15.3.2015 14:34

A co ty nejednoznacne vysledky u 3 a 4?:`

 
Nahoru Odpovědět 15.3.2015 14:34
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na hanpari
Jan Vargovský:15.3.2015 14:42

Tam je stejné. U toho listu se volá interně Array.Reverse, tak je to pomalejší jen o tu konverzi na list.

 
Nahoru Odpovědět 15.3.2015 14:42
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:15.3.2015 18:04

Škoda, že jsi nenapsal ty časy. Pochopil jsem to správně, že ten první byl cca 10x rychlejší než ten poslední? Asi sis nevšiml, jak to škáluje?

 
Nahoru Odpovědět 15.3.2015 18:04
Avatar
coells
Redaktor
Avatar
coells:15.3.2015 18:31

Jan Vargovský hanpari

Pánové, vy jste se nikdy nezabývali profilingem kritických sekcí aplikace, že? :-)

Schválně, za předpokladu, že kód je v C a optimalizace nezasáhne do instrukčního toku (což obvykle udělá), který kód bude rychlejší?

double sum = 0;
for (int i = 0; i < n; i++)
  sum = sum + array[i];

nebo

double sum = 0;
for (int i = 0; i < n; i++)
  sum = array[i] + sum;
Editováno 15.3.2015 18:32
 
Nahoru Odpovědět 15.3.2015 18:31
Avatar
Jiří Gracík
Redaktor
Avatar
Odpovídá na coells
Jiří Gracík:15.3.2015 18:37

To by mě zajímalo, spíš teda - bude v tom rozdíl?

Nahoru Odpovědět 15.3.2015 18:37
Creating websites is awesome till you see the result in another browser ...
Avatar
Odpovídá na Jiří Gracík
Michal Žůrek (misaz):15.3.2015 18:47

myslím, že v tom případě minimální, větší rozdíl by byl, kdyby první ukázka byla správně napsaná

double sum = 0;
for (int i = 0; i < n; i++)
  sum += array[i];
Nahoru Odpovědět 15.3.2015 18:47
Nesnáším {}, proto se jim vyhýbám.
Avatar
Odpovídá na coells
Neaktivní uživatel:15.3.2015 18:58

Podľa mňa bude druhá verzia o niečo rýchlejšia ako tá prvá, mám pravdu?

Nahoru Odpovědět 15.3.2015 18:58
Neaktivní uživatelský účet
Avatar
Odpovídá na Michal Žůrek (misaz)
Neaktivní uživatel:15.3.2015 19:00
sum += array[i];

je identické s

sum = sum + array[i];

je to iba skrátený zápis, ale oba výrazy sú preložené prekladačom rovnako.

Editováno 15.3.2015 19:00
Nahoru Odpovědět 15.3.2015 19:00
Neaktivní uživatelský účet
Avatar
coells
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
coells:15.3.2015 19:02

A můžeš to něčím podložit? Vzhledem k tomu, že se tvoje varianta nutně musí přeložit do jedné ze dvou nabízených verzí, to nedává moc smysl.

 
Nahoru Odpovědět 15.3.2015 19:02
Avatar
coells
Redaktor
Avatar
Odpovídá na Neaktivní uživatel
coells:15.3.2015 19:03

Máš pravdu! :)

 
Nahoru Odpovědět 15.3.2015 19:03
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:15.3.2015 21:03

Zajímavé,
nakonec jsem si zkusil napsat vlastní benchmark a výsledek je trochu jiný. Hlavně co se týče rychlosti s pomocí while cyklu (jméno: iterace). Tobě vyšel jako nejrychlejší, pokud se nepletu, zatímco mně jako druhý nejpomalejší. I když ty rozdíly mezi nejrychlejšími třemi jsou poměrně malé.

Length of tested sentence is: 20000 chars.
Number of repetion is: 10000
Starting to evaluate...

[Enumerace, 00:00:11.0784580]
[Iterace, 00:00:00.7929593]
[ListMethod, 00:00:00.4238042]
[CharArray, 00:00:00.2655176]

Pokud by se chtěl někdo podívat, ten benchmark je tady:

http://pastebin.com/JXXJK7e7

Použití je jednoduché :)

var benchmark = new Benchmark(delka_retezce, pocet_opakovani_funkce_za_sebou);
benchmark.PrintResults();
Editováno 15.3.2015 21:03
 
Nahoru Odpovědět 15.3.2015 21:03
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 25 zpráv z 25.