• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kilka operacji na tablicach w C++

Object Storage Arubacloud
0 głosów
1,054 wizyt
pytanie zadane 9 kwietnia 2017 w C i C++ przez TeslaX93 Gaduła (3,600 p.)
Więc sytuacja jest następująca.

Mam sobie tablicę stringów (AnsiString) o przykładowej treści

tekst1
tekst2
tekst2
tekst3
tekst4
tekst1
 

I potrzebuję:
a) usunąć duplikaty z tablicy, a zamiast pustych miejsc przesunąć resztę do góry,
b) w osobnej tablicy int zrobić statystyki ile razy występuje każdy tekst (np. tekst1 - 2)

I jako że duplikaty jakoś rozwiązałem poprzez wyszukiwanie, to nie mogę sobie poradzić z przesuwaniem rekordów (wywala błąd), no i nie wiem jak zaimplementować statystyki, no bo jak już usunę i przesunę, to nie pamiętam ile razy co występowało w tablicy :/ I nie mam pomysłu na to.

Program robię w C++Builder jeżeli ma to znaczenie.

3 odpowiedzi

+2 głosów
odpowiedź 9 kwietnia 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 9 kwietnia 2017 przez mokrowski

std::map ma klucze kojarzone z wartościami. Kluczem będzie u Ciebie słowo a wartością ilość jego wystąpień.

Dane wczytasz z użyciem std::istream_iterator.

Po tym jak zbudujesz mapę, wystarczy wyprowadzić jej klucze do pliku. :-)

Nie zaglądaj jeśli sam czegoś nie napisałeś :-)

#include <map>
#include <iostream>
#include <iterator>
#include <fstream>
#include <map>
#include <string>
#include <algorithm>
#include <cassert>

std::ifstream openFile(const std::string& fileName) {
    using namespace std;
    ifstream file(fileName);
    assert(file); // Kontrola otwarcia pliku.. 
    return file;
}

std::map<std::string, unsigned> countWord(std::ifstream& file) {
    using namespace std;
    using input_t = istream_iterator<string>;
    map<string, unsigned> wordCount;

    for_each(input_t(file), input_t(), [&wordCount](auto& word) {
        wordCount[word]++;
    });

    return wordCount;
}

void saveToFile(const std::string& fileName, const std::map<std::string, unsigned>& wordMap) {
    // Zapiszę słowo-klucz i ilość wystąpień.
    using namespace std;
    ofstream oFile(fileName);
    assert(oFile); // diagnostyka błędu otwarcia

    for_each(wordMap.cbegin(), wordMap.cend(), [&oFile](auto& pr) {
        oFile << pr.first << " " << pr.second << std::endl;
    });
}

int main() {
    auto file = openFile("wyrazy.txt");
    auto wordMap = countWord(file);
    saveToFile("wyniki.txt", wordMap);
}

Kompilować w trybie C++14

0 głosów
odpowiedź 10 kwietnia 2017 przez j23 Mędrzec (194,920 p.)
edycja 10 kwietnia 2017 przez j23

Upraszczając kod mokrowskiego:

AnsiString tab[] = { "tekst1", "tekst2", "tekst2", "tekst3", "tekst4", "tekst1" };
	
map<AnsiString, int> m;
	
for(auto &s : tab) m[s]++;
	
for(auto &i : m)
{
	cout << i.first << " - " << i.second << '\n';
}

tab może być tablicą, jak w przykładzie, lub innym STL-owym kontenerem.

 

--- dodane ---

Tu masz wersję zachowującą kolejność elementów:

AnsiString tab[] = { "tekst1", "tekst2", "tekst2", "tekst3", "tekst4", "tekst1" };
	
using map_t = map<AnsiString, int>;
using vec_t = vector<map_t::iterator>;
		
map_t m;
vec_t v;
	
for(auto &s : tab) 
{
	auto res = m.insert({s, 1});
	if(res.second) v.push_back(res.first);
	else ++res.first->second;
}
	
for(auto &i : v)
{
	cout << i->first << " - " << i->second << '\n';
}

 

1
komentarz 10 kwietnia 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 10 kwietnia 2017 przez mokrowski

E tam :-) Wolę swoje :-) Jest bardziej reużywalne ;-P Ale już poważniej.. W C++17 doszła nowa składnia for'a:

Zamiast tego:

auto res = m.insert({s, 1});
if(res.second) //... 

Będzie można zrobić tak:

if(auto res = m.insert({s, 1}); res.second) // ... 

Plusem (nie jedynym) może być pozostanie zmiennej w 1 zakresie. Inne zalety ujawniają się w nowej składni przypisań np:

auto [ it, ok ] = m.insert({a, 1});

Fajne bo rozpakuje tuple :-) (pachnie Pythonem) .. 

Ja wolę podawać tu nowoczesne przykłady bo "kodem legacy" już... wymiotuję..  :-(

PS. A po co Ci ten vector jak możesz robić inserty od razu do mapy? Bo do wersji z zachowaniem kolejności oczywiście się broni....

komentarz 10 kwietnia 2017 przez j23 Mędrzec (194,920 p.)

Wolę swoje :-)

To nie jest kwestia tego, co kto woli, tylko co OP z tego zrozumie ;)

 

Bo do wersji z zachowaniem kolejności oczywiście się broni....

I tylko tam jest użyty.

komentarz 10 kwietnia 2017 przez mokrowski Mędrzec (155,460 p.)

To nie jest kwestia tego, co kto woli... 

tylko reużywalności :-)

A co do problemu a) w pierwotnym poście, gdyby był pojedynczo rozpatrywany. warto zerknąć do stable_sort i unique z algorytmów. Stable bo nie zmieni kolejności a posortuje a unique bo zwróci unikalne. Ale jak jest to zrobione w mapie i w połączeniu z innym problemem to po co?

komentarz 10 kwietnia 2017 przez j23 Mędrzec (194,920 p.)

Nie rozumiem pytania. Odnośnie czego konkretnie ono jest?

 

Stable bo nie zmieni kolejności (...)

Nie zmieni kolejności elementów równych. Przy tym problemie to bez znaczenia.

0 głosów
odpowiedź 10 kwietnia 2017 przez Evelek Nałogowiec (28,960 p.)
Usunąć duplikaty z tablicy - rozwiązałeś przez wyszukiwanie? Rozumiem, że dla 100 elementów zrobiłeś pętlę for która się wykonała 100 razy i porównała wszystkie obiekty string. Dla 100 elementów należy wykonać 100! (silnia) takich operacji. Da radę szybciej - najpierw posortuj te elementy a potem porównuj parami czy się powtarzają. Tutaj masz sortowanie + 100 porównań co działa w trybie ekspresowym.
komentarz 10 kwietnia 2017 przez j23 Mędrzec (194,920 p.)

To rozwiązanie pierwsze mi się nasunęło. Pytanie tylko, czy musi zachować kolejność... choć i to dałoby się zrobić, podobnie jak z mapą. Tak czy siusiak, dwie funkcje będą pomocne: str::sort i std::unique.

Podobne pytania

0 głosów
1 odpowiedź 113 wizyt
0 głosów
1 odpowiedź 89 wizyt
pytanie zadane 13 marca 2020 w C i C++ przez MiKasProgramista Początkujący (350 p.)
0 głosów
0 odpowiedzi 132 wizyt
pytanie zadane 24 stycznia 2020 w C i C++ przez Jan Patryk Kowalski Obywatel (1,880 p.)

92,573 zapytań

141,423 odpowiedzi

319,648 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...