Diskuze: Jak otočit slovo?

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

Avatar
michaelbeats7:

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ý:
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:

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):

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ý:

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:

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):

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:

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ý:

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ý:

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:

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ý:

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:

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ý:

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:

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ý:

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:

Š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:

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:

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):

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:

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:
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:

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
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Jan Vargovský
hanpari:

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.