Ananagramy z podanego zbioru słów

Ananagramy z podanego zbioru słów
R9
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 12 lat
  • Postów:39
0

Witam. Mam do napisania program wypisujący ananagramy z podanego zboru słów. Ananagram to wyraz, w którym nie da się tak zmienić kolejności liter aby uzyskać nowe słowo. Takie przeciwienstwo do anagramu. Program nie moze potrafic okreslic czy przestawione litery tworza poprawne slowo dlatego na wejsciu podajemu slownik (czyli wspomniany zbior wyrazow).

Przykladowo jak na wejsciu podamy zbior slow:

abc, cba, def, gHi, hGi

to program na wyjsciu ma wyswietlic slowo:
def

gdyż jest to ananagram w tym zbiorze, a pary abc i cba oraz gHi i hGi sa anagramami.

Wielkosc liter nie ma znaczenia!

Napisalem program wczytujacy zbior wyrazow do tablicy. Tworze kopie tej tablicy.

Wszystkie litery w wyrazach wejsciowych zamieniam na wielkie i sortuje je.

Tylko teraz nie wiem jak przeszukac te zbiory i znalezc ananagramy. Myslalem o uzyciu stlowej funkcji nex_permutation ale nie wiem czy to dobry sposob.

Kopiuj
#include <iostream>
#include <string>
#include <algorithm>
#include <stdio.h>

using namespace std;

int main()
{
string wejscie[1000];
string wynik[1000];
string kopia[1000];
int i=0;
cin >> wejscie[i];
kopia[i]=wejscie[i];

//zadawanie wyrazow
while (wejscie[i][0] != '#')
{
    i++;
    cin >> wejscie[i];
    kopia[i]=wejscie[i];
}


//sortowanie liter w kazdym wyrazie
for (int j=0; j<i; j++)
{
    sort(wejscie[j].begin(), wejscie[j].end());
}

//zamiana wszystkich liter na duze w wyrazach wejsciowych
for (int x=0; x<i; x++)
{
    transform(wejscie[x].begin(), wejscie[x].end(), wejscie[x].begin(), ::toupper);
}




cout << endl;

//wypisanie wszystkich wyrazow skopiowanych
for(int j=0; j<i; j++)
{
    cout << kopia[j]<<  endl;
}

cout << endl;

//wypisanie wszystkich wyrazow wejsciowych po zmianie wielkosci liter
for(int j=0; j<i; j++)
{
    cout << wejscie[j]<<  endl;
}


return 0;
}
 

KR
  • Rejestracja:prawie 16 lat
  • Ostatnio:5 miesięcy
  • Postów:2514
0

a nie łatwiej zliczyć ilości liter i na tej podstawie stwierdzić czy wyraz może lub nie może być anagramem? (sprawdzić czy w ogóle może nim być). można też pogrupować wyrazy na długości, bo żeby wyraz mógł być anagramem innego musi mieć tą samą długość. (chyba, że coś źle zrozumiałem)


░█░█░█░█░█░█░█░█░█░█░█░
edytowany 3x, ostatnio: krwq
R9
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 12 lat
  • Postów:39
0
krwq napisał(a)

a nie łatwiej zliczyć ilości liter i na tej podstawie stwierdzić czy wyraz może lub nie może być anagramem? (sprawdzić czy w ogóle może nim być). można też pogrupować wyrazy na długości, bo żeby wyraz mógł być anagramem innego musi mieć tą samą długość. (chyba, że coś źle zrozumiałem)

Może i łatwiej, ale nie wpadło mi to wcześniej dogłowy.
Postanowiałem posortować wyrazy i litery w zbiorze i sprawdzić, czy sąsiednie się różnia. Jeśli tak to powinny być ananagramimi. Ale nie działa do końca.

Kopiuj
#include <iostream>
#include <string>
#include <algorithm>
#include <stdio.h>

using namespace std;

int main()
{
string wejscie[1000];
string kopia[1000];
string temp;
string temp2;
int i=0;

cin >> wejscie[i];
kopia[i]=wejscie[i];

//zadawanie wyrazow
while (wejscie[i][0] != '#')
{
    i++;
    cin >> wejscie[i];
    kopia[i]=wejscie[i];
}


//sortowanie liter w kazdym wyrazie
for (int j=0; j<i; j++)
{
    sort(wejscie[j].begin(), wejscie[j].end());
}

//sortowanie wyrazow wejsciowych

for (int k = 0; k<i; k++)
                for (int j=0; j<i-1; j++)
                        {
                                if (wejscie[j] > wejscie[j+1])
                                {
                                        temp = wejscie[j+1];
                                        wejscie[j+1] = wejscie[j];
                                        wejscie[j] = temp;
                                }
                        }

// sortowanie skopiowanych wyrazow
for (int k = 0; k<i; k++)
                for (int j=0; j<i-1; j++)
                        {
                                if (kopia[j] > kopia[j+1])
                                {
                                        temp2 = kopia[j+1];
                                        kopia[j+1] = kopia[j];
                                        kopia[j] = temp2;
                                }
                        }

//zamiana wszystkich liter na duze w wyrazach wejsciowych
for (int x=0; x<i; x++)
{
    transform(wejscie[x].begin(), wejscie[x].end(), wejscie[x].begin(), ::toupper);
}

cout << endl;

for(int j=0; j<i-1; j++)
{
    if(wejscie[j] != wejscie[j+1])
    cout << kopia[j+1]<< endl;
}



return 0;
}
 

merlinnot
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 lat
  • Lokalizacja:Wrocław
  • Postów:292
1

A nie prościej wczytać poszczególne zbiory liter do tablicy stringów, posortować te stringi i porównywać każdy string z kolejnymi w tablicy, jeżeli są takie same, to oznaczyć obydwa jako anagramy? Dla twojego przykładu:
abc, cba, def, gHi, hGi
sprawdzasz abc z posortowanymi cba, def, gHi, hGi;
cba z def,
def z gHi, hGi;
itd. Sprawdzanie, czy stringi są takie same jest bardzo proste:

Kopiuj
 #include <iostream>
#include <string>
#define usi unsigned short int
using namespace std;
int main() {
	string a, b;
	cin >> a >> b;
	if (a==b) cout << "TU\n";
	else
	if (a<b) cout << "WCZESNIEJ\n";
	else
	if (a>b) cout << "DALEJ\n";
}

ewentualnie funkcja

Kopiuj
strcmp ( const char * str1, const char * str2 );

.
Ale jeżeli chcesz to mieć w tablicy, to możesz użyć podobnej funkcji:

Kopiuj
memcmp ( const void * ptr1, const void * ptr2, size_t num );
edytowany 1x, ostatnio: merlinnot
KR
albo std::lexicographical_compare
Xitami
  • Rejestracja:ponad 20 lat
  • Ostatnio:około rok
1
Kopiuj
int cmp(char * a, char * b){ 
	return *a - *b;}
	
main(){
	char t[100][20]; 
	char a[100][20];
	char s     [20];
	int  n=0, i;
	while( 0 < scanf("%s", s) ){
		for( i=0; 0<s[i]; i++ ) 
			t[n][i]= tolower(s[i]);
		t[n][i]=0; 
		qsort(t[n], strlen(s), 1, cmp); 
		strcpy(a[n], s);
		for( i=0; strcmp(t[i], t[n]); i++ ) 
			;
		if( i < n ) { a[n][0]=0; a[i][0]=0; }
		else n++; }
	for( i=0; i<n; i++)
		puts(a[i]); }

http://ideone.com/oJSDd

O(n^2) bo proste liniowe szukanie

edytowany 1x, ostatnio: Xitami
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:7 minut
1

Ja bym zaczął od wymyślenia jakiegoś sprytnego hash-a. Coś w stylu:
((Liczba unikatowych liter * c + id litery najczęstszej lub pierwszej leksykalnie) * c + id następnej takiej litery) * c + id następnej takiej litery
gdzie c to dopuszczalna liczba rożnych liter.
równość hashy to warunek koniczny, by dwa wyrazy były anagramami, więc wstępnie można szybko pogrupować wyrazy, a potem sprawdzać warunek wystarczający w ramach każdej grupy.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
R9
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 12 lat
  • Postów:39
0

Wczytałem do tablicy stringow, gdzie kolejno zmienilem wszystkie litery na male, posortowalem litery, nastepnie kazdy taki ciag znakow porownywalem z pozostalymi. Jesli byl jakis unikalny to w tablicy intow przypisywalem dla tego elementu 1. Potem odpowiednie elementy z pierwotnej tablicy wyrazow posortowalem i wypisalem.

Wasze wypowiedzi okazaly sie bardzo pomocne.

Leca plusiki. dziekuje i pozdrawiam.


Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)