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

anagramy spoj

VPS Starter Arubacloud
0 głosów
520 wizyt
pytanie zadane 3 września 2017 w SPOJ przez chucksqll Stary wyjadacz (12,930 p.)
Witam. Robię zadanie ze spoj'a, niestety dość nieudolnie.

http://pl.spoj.com/problems/AL_30_01/

1 przypadek błędna odpowiedź, chociaż dla wymyślonych przeze mnie przypadków działa, więc 1 pytanie czy podane rozwiązanie jest poprawne?

https://ideone.com/gsj2hG kod.

Uznałem, że jest błędne, dlatego napisałem inną wersję z użyciem sortowania bąbelkowego stringów. Przy drugiej jest przekroczony limit czasu, a czasami " Błędna odpowiedź ". To rozwiązanie też jest błędne czy zwyczajnie sortowanie zajmuje za dużo czasu?

https://ideone.com/669AEy 2 kod.

Z góry dziękuję za pomoc.
komentarz 3 września 2017 przez niezalogowany

Dla 1 sprawdź taki test:

Wejście:
hibdzioo 1
chibdzio

Wychodzi 1, a powinno 0.

2 odpowiedzi

+1 głos
odpowiedź 3 września 2017 przez niezalogowany
edycja 3 września 2017
 
Najlepsza

Masz błąd w sortowaniu bąbelkowym. Iterator 'i' nie musi mieć ograniczenia w postaci wyraz.length()-1. Przez to nie sprawdzasz ostatniej litery. Dodatkowo można by sortować anagram tylko raz, a nie tyle razy ile jest testów do sprawdzenia:

#include <iostream>
#include <string>
using namespace std;

void sortowaniebabelkowe(string &wyraz)
{

	for (int i = 0; i<wyraz.length() ; i++)
	{
		for (int j = 0; j<wyraz.length() - 1; j++)
		{
			if (int(wyraz[j])>int(wyraz[j + 1]))

				swap(wyraz[j], wyraz[j + 1]);
		}
	}
}

int main()
{
	string anagram;
	int n;
	int licznik = 0;
	cin >> anagram;
	cin >> n;
	sortowaniebabelkowe(anagram);

	for (int i = 0; i<n; i++)
	{
		string czyanagram;
		cin >> czyanagram;
		if (anagram.length() == czyanagram.length())
		{
			sortowaniebabelkowe(czyanagram);
			if (anagram == czyanagram)
				licznik++;
		}
	}
	cout << licznik;
}

Mi taki kod zaliczyło na granicy poprawności (0.97s, a limit jest 1s). Mógłbyś zamiast sortowania bąbelkowego użyć funkcji sort:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
	string anagram;
	int n;
	int licznik = 0;
	cin >> anagram >> n;
	sort(anagram.begin(), anagram.end());

	for (int i = 0; i<n; i++)
	{
		string czyanagram;
		cin >> czyanagram;
		if (anagram.length() == czyanagram.length())
		{
			sort(czyanagram.begin(), czyanagram.end());
			if (anagram == czyanagram)
				licznik++;
		}
	}
	cout << licznik;
}

[EDIT]: Można też użyć funkcji is_permutation:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
	string anagram;
	int n;
	int licznik = 0;
	cin >> anagram >> n;

	for (int i = 0; i<n; i++)
	{
		string czyanagram;
		cin >> czyanagram;
		if (anagram.length() == czyanagram.length())
			if (is_permutation(anagram.begin(), anagram.end(), czyanagram.begin())) 
				licznik++;
	}
	cout << licznik;
}
0 głosów
odpowiedź 3 września 2017 przez mokrowski Mędrzec (156,260 p.)
edycja 3 września 2017 przez mokrowski
To nie jest dobra droga rozwiązania. Zlicz wystąpienia znaków w obu stringach (wzorzec i kandydat na anagram). Jeśli są równe, to jest to anagram;)
komentarz 10 września 2017 przez niezalogowany
edycja 14 września 2017
Można prosić o jakiś przykład w nowoczesnym C++?
komentarz 10 września 2017 przez mokrowski Mędrzec (156,260 p.)

A proszę...

Czas 0.04 pamięć 16M

#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
 
std::unordered_map<char, short unsigned> make_map(const std::string& msg) {
    std::unordered_map<char, short unsigned> msg_map;
    for(const char& ch: msg) {
        msg_map[ch] += 1;
    }
    return msg_map;
}
 
int main() {
    size_t counter;
    std::string message, anagram_candidate;
    std::cin >> message >> counter;
    auto message_map{make_map(message)};
    size_t anagram_counter{};
    while(counter-->0) {
        std::cin >> anagram_candidate;
        message_map == make_map(anagram_candidate) && anagram_counter++;
    }
    
    std::cout << anagram_counter;
}

Po optymalizacji i zrezygnowaniu z wysokopoziomowych konstrukcji

Czas wykonania 0.00 pamięć 2.7M


#include <cstdio>
#include <cstring>
 
static const size_t table_size = 'z' - 'a' + 1;
 
void count_chars(const char * msg, size_t size, unsigned short * chars_counted) {
    std::memset(chars_counted, 0, table_size * sizeof(unsigned short));
    while(size-->0) {
        chars_counted[msg[size] - 'a']++;
    }
}
 
int main() {
    char msg[1001];
    char anagram_candidate[1001];
    unsigned short msg_table[table_size];
    unsigned short candidate_table[table_size];
    unsigned counter;
    unsigned anagram_counter = 0;
 
    std::scanf("%1000s %u", msg, &counter);
    const size_t msg_len = std::strlen(msg);
    count_chars(msg, msg_len, msg_table);
 
 
    while(counter-->0) {
        std::scanf("%1000s", anagram_candidate);
        count_chars(anagram_candidate, std::strlen(anagram_candidate), candidate_table);
        if(std::memcmp(candidate_table, msg_table, table_size) == 0) {
            anagram_counter++;
        }
    }
    std::printf("%u", anagram_counter);
}

 

komentarz 11 września 2017 przez niezalogowany
Dziękuję!

Podobne pytania

0 głosów
3 odpowiedzi 1,896 wizyt
pytanie zadane 14 marca 2018 w C i C++ przez Nic_Nie_Wiem Nowicjusz (120 p.)
0 głosów
2 odpowiedzi 699 wizyt
pytanie zadane 26 czerwca 2015 w Offtop przez Anonim Mądrala (6,000 p.)
0 głosów
3 odpowiedzi 1,866 wizyt
pytanie zadane 18 maja 2015 w C i C++ przez MrLoyt Nowicjusz (120 p.)

92,979 zapytań

141,943 odpowiedzi

321,189 komentarzy

62,308 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.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...