Autor Téma: Práce s textem  (Přečteno 651 krát)

Offline AlienStar

  • Mladík
  • **
  • Příspěvků: 99
  • Karma: 2
Práce s textem
« kdy: 16-04-2018, 21:07:22 »
Dobrý den.

Řeším jedem problém.
Mám seznam textu  .. např:

jahoda
jablko
jahoda
hruska
jahoda
jablko
jahoda

A potřebuji do StringGridu vypsat součty stejných textů a seřadit od největšího počtu.
Výsledek by měl vypadat takto:

jahoda    4
jablko     2
hruska    1


Jak na to?
děkuji Milan

Offline raul

  • Plnoletý
  • ***
  • Příspěvků: 237
  • Karma: 12
    • Verze Delphi: FPC :D
Re:Práce s textem
« Odpověď #1 kdy: 16-04-2018, 21:28:52 »
Treba sort, pak project, pocitat a plnit grid ?
Lazarus 1.6.3:), FPC, Intel/Arm, Windows/Linux

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Práce s textem
« Odpověď #2 kdy: 16-04-2018, 23:08:55 »
Databaza a SQL:
Kód: MySQL [Vybrat]
  1. SELECT TypOvoce, Count( * ) AS Pocet
  2.         FROM tabulkaOvoce
  3.         GROUP BY TypOvoce
nie som si isty, ci je mozny sort hned, ale takto urcite:
Kód: MySQL [Vybrat]
  1. SELECT TypOvoce, Pocet FROM
  2.         (
  3.         SELECT TypOvoce, Count( * ) AS Pocet
  4.                 FROM tabulkaOvoce
  5.                 GROUP BY TypOvoce
  6.         )
  7.         ORDER BY Pocet desc, TypOvoce


Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Práce s textem
« Odpověď #3 kdy: 16-04-2018, 23:18:22 »
Great
Rated 1 time
Jedna z moznosti ktera by mela fungovat i na "starych" Delphi je napr.:

Kód: Delphi [Vybrat]
  1. function Comparer(List: TStringList; Index1, Index2: Integer): Integer;
  2. begin
  3.   Result := CompareValue(Integer(List.Objects[Index2]), Integer(List.Objects[Index1]));
  4. end;
  5.  
  6. procedure TForm1.Button1Click(Sender: TObject);
  7. var
  8.   S: string;
  9.   I: Integer;
  10.   Index: Integer;
  11.   Input: TStringList;
  12.   Output: TStringList;
  13. begin
  14.   Input := TStringList.Create;
  15.   try
  16.     Input.LoadFromFile('C:\InputFile.txt');
  17.     Output := TStringList.Create;
  18.     try
  19.       for I := 0 to Input.Count - 1 do
  20.       begin
  21.         S := Input[I];
  22.         Index := Output.IndexOf(S);
  23.         if Index = -1 then
  24.           Output.AddObject(S, TObject(Integer(1)))
  25.         else
  26.           Output.Objects[Index] := TObject(Integer(Output.Objects[Index]) + 1);
  27.       end;
  28.  
  29.       Output.CustomSort(Comparer);
  30.  
  31.       StringGrid1.RowCount := Output.Count;
  32.       StringGrid1.ColCount := 2;
  33.       StringGrid1.FixedRows := 0;
  34.       StringGrid1.FixedCols := 0;
  35.       for Index := 0 to Output.Count - 1 do
  36.       begin
  37.         StringGrid1.Cells[0, Index] := Output[Index];
  38.         StringGrid1.Cells[1, Index] := IntToStr(Integer(Output.Objects[Index]));
  39.       end;
  40.     finally
  41.       Output.Free;
  42.     end;
  43.   finally
  44.     Input.Free;
  45.   end;
  46. end;

Jinak preju hodne zdaru uciteli vyucujicimu Delphi v teto dobe ;)
« Poslední změna: 16-04-2018, 23:22:30 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline JaroB

  • Guru
  • *****
  • Příspěvků: 894
  • Karma: 25
    • Verze Delphi: XE8, Seattle
Re:Práce s textem
« Odpověď #4 kdy: 17-04-2018, 08:32:30 »
Excellent
Rated 1 time
A není jednodušší, pokud je tedy seznam v nějakém listu, nejdříve deduplikovat seznam a pak v druhém průběhu nasčítat počty stejných?
Zkusil jsem to klasicky jako cvičení na dva listboxy a jedno tlačítko. V jednom je tvůj seznam a do druhého to nasypu.

Kód: Delphi [Vybrat]
  1. var
  2.   t: TStringList;
  3.   i, j, c: Integer;
  4. begin
  5.   t := TStringList.Create;
  6.   try
  7.     t.Duplicates := dupIgnore;
  8.     t.Sorted := True;
  9.     //deduplikace
  10.     for i := 0 to ListBox1.Items.Count - 1 do
  11.       t.Add(ListBox1.Items[i]);
  12.     t.Duplicates := dupAccept;
  13.     t.Sorted := False;
  14.     //nascitani
  15.     for i := 0 to ListBox1.Items.Count - 1 do
  16.     begin
  17.       j := t.IndexOf(ListBox1.Items[i]);
  18.       if j <> -1 then
  19.       begin
  20.         c := Integer(t.Objects[j]);
  21.         inc(c);
  22.         t.Objects[j] := Pointer(c)
  23.       end;
  24.     end;
  25.     //setrideni
  26.     ListBox2.Items.Clear;
  27.     for i := 0 to t.Count-1 do
  28.       ListBox2.Items.Add(Format('%.*d',[4, Integer(t.Objects[i])]) + '=' + t[i]);
  29.     t.Assign(ListBox2.Items);
  30.     t.Sort;
  31.     ListBox2.Items.Clear;
  32.     for i := t.Count - 1 downto 0 do
  33.       ListBox2.Items.Add(Copy(t[i], Pos('=', t[i]) + 1) + ' = ' + IntToStr(StrToInt(Copy(t[i], 1, Pos('=', t[i]) - 1))));
  34.   finally
  35.     t.Free
  36.   end;
  37.  

Offline AlienStar

  • Mladík
  • **
  • Příspěvků: 99
  • Karma: 2
Re:Práce s textem
« Odpověď #5 kdy: 17-04-2018, 12:11:07 »
@JaroB - To vypadá dobře .... děkuji

předělal jsem to do StringGridu,, ale to seřazení v něm nějak nedávám

Kód: Delphi [Vybrat]
  1. procedure TForm5.Button1Click(Sender: TObject);
  2. var
  3.   t: TStringList;
  4.   i, j, c: Integer;
  5. begin
  6.   t := TStringList.Create;
  7.   try
  8.     t.Duplicates := dupIgnore;
  9.     t.Sorted := True;
  10.     //deduplikace
  11.     for i := 1 to StringGrid7.RowCount -1 do
  12.     t.Add(StringGrid7.Cells[4,i]);
  13.     t.Duplicates := dupAccept;
  14.     t.Sorted := False;
  15.     //nascitani
  16.     for i := 0 to StringGrid7.RowCount -1 do
  17.     begin
  18.       j := t.IndexOf(StringGrid7.Cells[4,i]);
  19.       if j <> -1 then
  20.       begin
  21.         c := Integer(t.Objects[j]);
  22.         inc(c);
  23.         t.Objects[j] := Pointer(c)
  24.       end;
  25.     end;
  26.     //setrideni
  27.  
  28. .... ???
  29.  
  30.  

načtu hodnoty z StringGrid7 a zapíšu je seřazené do StringGrid9
Ale jak je ve StringGrid9 seřadit ?


Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Práce s textem
« Odpověď #6 kdy: 17-04-2018, 15:31:45 »
A není jednodušší, pokud je tedy seznam v nějakém listu, nejdříve deduplikovat seznam a pak v druhém průběhu nasčítat počty stejných?

V cem by to melo byt jednodussi? Vzdyt to pocitani duplikatu muzes udelat pri jednom pruchodu zdrojovym listem.
« Poslední změna: 17-04-2018, 15:33:48 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Jan

  • Host
Re:Práce s textem
« Odpověď #7 kdy: 17-04-2018, 20:55:58 »
Je potřeba použít jeden s řadících algoritmů.
Viz. https://www.algoritmy.net/article/75/Porovnani-algoritmu

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Práce s textem
« Odpověď #8 kdy: 17-04-2018, 22:01:35 »
Zoradenie predsa poskytuje TStringList.
Ten však zoraďuje texty, nie čísla. Preto je treba čísla naformátovať s vodiacimi nulami:
Kód: Delphi [Vybrat]
  1. Format( '%0.3d', [ mojeCislo] )
Takýto zoznam sa potom ľahko zoradí. Napr. pre tento zoznam
002=jablko
004=hruška
003=marhuľa
sa využije sort a potom sa  vymenia položky takto:
Kód: Delphi [Vybrat]
  1. slZoznam.Sort;
  2. for i := 0 to slZoznam.Count-1 do
  3.   slZoznam.Values[slZoznam.Names[I]]=slZoznam.Names[I];
Naplnenie stringGridu je len hračka..
SQLite databáza a SQL príkazy, presne takéto úlohy riešia omnoho elegantnejšie a dokonalejšie. StringGrid sa nahradí dbGridom. Úloha je hotová za zlomok času. Pritom sa otvárajú nekonečné možnosti úprav a vylepšení.
« Poslední změna: 17-04-2018, 22:04:38 od Miroslav Baláž »

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Práce s textem
« Odpověď #9 kdy: 17-04-2018, 22:03:52 »
Vy uz tu stavite raketoplan ;D Poslal jsem kompletni reseni s ukladanim poctu vyskytu do pole objektu kolekce s vyuzitim custom sort bez zbytecnosti navic ;) Asi jen ztrata casu ::) :)
« Poslední změna: 17-04-2018, 22:06:43 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Práce s textem
« Odpověď #10 kdy: 18-04-2018, 00:06:13 »
Ten však zoraďuje texty, nie čísla. Preto je treba čísla naformátovať s vodiacimi nulami:
Kód: Delphi [Vybrat]
  1. Format( '%0.3d', [ mojeCislo] )

Proto je k dispozici CustomSort ;)

SQLite databáza a SQL príkazy, presne takéto úlohy riešia omnoho elegantnejšie a dokonalejšie. StringGrid sa nahradí dbGridom. Úloha je hotová za zlomok času. Pritom sa otvárajú nekonečné možnosti úprav a vylepšení.

Moc me nenapada co by se dalo vylepsit na scitani ovoce ;D Navic tohle vypada jako domaci ukol ;)
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Práce s textem
« Odpověď #11 kdy: 18-04-2018, 00:28:27 »
Vylepšiť by sa dal zápis do string gridu (nulová námaha) a mnohé nové budúce požiadavky, pretože tie rastú vždy.
A dík za pripomienku Custom sort.

Offline AlienStar

  • Mladík
  • **
  • Příspěvků: 99
  • Karma: 2
Re:Práce s textem
« Odpověď #12 kdy: 18-04-2018, 11:00:17 »
Poradíte mi prosím ještě k tomuto? mockrát děkuji

@JaroB - To vypadá dobře .... děkuji

předělal jsem to do StringGridu,, ale to seřazení v něm nějak nedávám

Kód: Delphi [Vybrat]
  1. procedure TForm5.Button1Click(Sender: TObject);
  2. var
  3.   t: TStringList;
  4.   i, j, c: Integer;
  5. begin
  6.   t := TStringList.Create;
  7.   try
  8.     t.Duplicates := dupIgnore;
  9.     t.Sorted := True;
  10.     //deduplikace
  11.     for i := 1 to StringGrid7.RowCount -1 do
  12.     t.Add(StringGrid7.Cells[4,i]);
  13.     t.Duplicates := dupAccept;
  14.     t.Sorted := False;
  15.     //nascitani
  16.     for i := 0 to StringGrid7.RowCount -1 do
  17.     begin
  18.       j := t.IndexOf(StringGrid7.Cells[4,i]);
  19.       if j <> -1 then
  20.       begin
  21.         c := Integer(t.Objects[j]);
  22.         inc(c);
  23.         t.Objects[j] := Pointer(c)
  24.       end;
  25.     end;
  26.     //setrideni
  27.  
  28. .... ???
  29.  
  30.  

načtu hodnoty z StringGrid7 a zapíšu je seřazené do StringGrid9
Ale jak je ve StringGrid9 seřadit ?



Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Práce s textem
« Odpověď #13 kdy: 18-04-2018, 11:54:50 »
Napríklad takto:
Kód: Delphi [Vybrat]
  1. Format( '%0.3d=%s', [ mojeCislo, mojText] )
naplní jeden riadok TStringListu ( napr: mojList )
Ukážka riadku: "002=jablká"
Spravíš celý cyklus.
Na záver zoradíš ( mojList.Sort ).
Potom v novom cykle prepíšeš kam a ako potrebuješ.


 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: