I'm trying to sort German words with their articles, but it don't work perfectly. Can you help me?
Code:
#include <iostream>
#include <fstream>
#include <cstring>
#include <stdio.h>
using namespace std;
struct asd
{
string ne;
string fn;
};
int main()
{
asd szavak[50];
ifstream be("nemet.txt");
int db=0;
while (!be.eof())
{
be>>szavak[db].ne;
be>>szavak[db].fn;
cout<<szavak[db].ne<< " "<<szavak[db].fn<<endl;
db ;
}
be.close();
cout<< "\n\n"<< "Rendezve:\n";
for (int i=0; i<db-1; i )
{
for (int j=i 1; j<db; j )
{
if (szavak[j].ne<szavak[i].ne)
{
swap(szavak[j].ne,szavak[i].ne);
swap(szavak[j].fn,szavak[i].fn);
}
}
}
int sv1=0;
int sv2=0;
int sv3=0;
for (int i=0; i<db; i )
{
if (szavak[i].ne=="das")
{
sv1 ;
}
if (szavak[i].ne=="der")
{
sv2 ;
}
if (szavak[i].ne=="die")
{
sv3 ;
}
}
for (int j=0; j<sv1-1; j )
{
for (int k=j 1; k<sv1; k )
{
if (szavak[k].fn<szavak[j].fn)
{
swap(szavak[k].fn,szavak[j].fn);
}
}
}
for (int h=sv1; h<sv1 sv2-1; h )
{
for (int f=h 1; f<sv2; f )
{
if (szavak[f].fn<szavak[h].fn)
{
swap(szavak[f].fn,szavak[h].fn);
}
}
}
for (int s=sv1 sv2; s<sv1 sv2 sv3-1; s )
{
for (int l=s 1; l<sv3; l )
{
if (szavak[l].fn<szavak[s].fn)
{
swap(szavak[l].fn,szavak[s].fn);
}
}
}
for (int i=0; i<db; i )
{
cout<<szavak[i].ne<< " "<<szavak[i].fn<<endl;
}
return 0;
}
I expected it to sort the words correctly after 'das' too, but it didn't.
Here are the words that I used in the txt(one word in one line):
der Hafen
die Anzeige
das Einfamilienhaus
das Mehrfmilienhaus
der Mitbewohner
die Miete
die Badewanne
das Badezimmer
das Wohnzimmer
die Aussicht
das Arbeitszimmer
die Decke
der Plattenbau
der Altbau
der Neubau
der Hund
das Zimmer
das Bild
der Spiegel
die Kindern
die Waschmaschine
CodePudding user response:
I haven't checked the validity of your code (it's a bit hard to read), but you should always resort to the algorithms supplied by the standard library (unless of course you want to learn how to write sorting algorithms). This helps to prevent bugs like this. In your case you can use the std::sort
algorithm if you provide a comparison function for asd
which only compares ne
.
Sorting based on ne
The following example provides the comparison function in form of a lambda expression.
std::sort(
std::begin(szavak),
std::end(szavak),
[](asd const& a, asd const& b){ return a.ne < b.ne; }
);
for (auto const& a : szavak){
std::cout << a.ne << " " << a.fn << std::endl;
}
Output:
das Einfamilienhaus
das Mehrfmilienhaus
das Badezimmer
das Wohnzimmer
das Bild
das Arbeitszimmer
das Zimmer
der Hafen
der Mitbewohner
der Spiegel
der Plattenbau
der Altbau
der Neubau
der Hund
die Waschmaschine
die Kindern
die Decke
die Aussicht
die Badewanne
die Miete
die Anzeige
See here for a live code example
Sorting first by ne
, then by fn
If you want to sort first by article, then by noun, you can wrap ne
and fn
in tuples using std::tie
. tuples are by default compared lexicographically
std::sort(
std::begin(szavak),
std::end(szavak),
[](asd const& a, asd const& b){
return std::tie(a.ne, a.fn) < std::tie(b.ne, b.fn);
}
);
Output:
das Arbeitszimmer
das Badezimmer
das Bild
das Einfamilienhaus
das Mehrfmilienhaus
das Wohnzimmer
das Zimmer
der Altbau
der Hafen
der Hund
der Mitbewohner
der Neubau
der Plattenbau
der Spiegel
die Anzeige
die Aussicht
die Badewanne
die Decke
die Kindern
die Miete
die Waschmaschine
See here for a live code example
Bubble sort
If you do want to learn how to write a sorting algorithm, I would start by assuming that you have a comparison function for the elements in your array that returns true
, if two elements are in order and false
otherwise. Then you write your sorting algorithm with the use of this comparison function.
This makes your sorting algorithm more general, as you could pass in any comparison function you like. In addition, you can concentrate on the algorithm itself without having to worry about the types of objects that you are sorting or the criterium by which you are sorting them.
A simple bubble sort implementation based on forward iterators and a callable Comparator
object could look like this:
template <typename ForwardIt, typename Comparator>
void sort(ForwardIt begin, ForwardIt end, Comparator const& comp)
{
bool is_sorted = false;
while (!is_sorted){
is_sorted = true; // assume the container is sorted for now
ForwardIt current = begin;
ForwardIt next = current;
next;
while(next != end){
if (!comp(*current, *next)) {
/* swap them and remember something changed */
std::iter_swap(current, next);
is_sorted = false;
}
current;
next;
}
}
}
Note that the implementation makes no assumption on the type of objects in the array and no assumption on the criterium by which they shall be sorted. You only use
- an iterator
current
pointing to an element in the list that can be incremented to obtain thenext
element in the list std::iter_swap
to swap the values that two iterators point to.- A templated
Comparator
function, which must be invokable on two const references to objects in the list and return abool
.