[C++] Ordinare array di string (case sensitive)

Svpam

Nuovo Utente
70
2
CPU
intel core i5-2310m
HDD
1TB Western digital 5400rpm
RAM
8gb ddr3
GPU
amd ati 7310m
Monitor
samsung E2220
OS
Windows 7; ubuntu 14.04; Kali linux; debian 7
Scrivere un programma C++ che letti da input, nell’ordine, una stringa S, un intero N, ed un elenco di N stringhe (con N >=2) stampi “OK” se nell’elenco sono presenti due stringhe che concatenate danno N. Altrimenti, stampi la stringa che si ottiene concatenando la più grande dell’elenco con la più piccola secondo l’ordine alfabetico. Esempi: Se l’input fosse Domjudge 4 judge dono stella Dom il programma dovrebbe stampare OK. Se l’input fosse Domjudge 5 judge dono stella dom luce il programma dovrebbe stampare stelladom.

Codice:
/*
*
*    Ordina male maiuscole e minuscole, PROVA-BC-esame-ab
*    risulta PROVABC invece di esameab!!
*
*/

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>

using namespace std;


int main()
{
    string s;
    unsigned n;

    cin>>s;
    cin>>n;

    string *parole=new string[n];
    string *s1=new string [n];
    string *s2=new string[n];

    for(unsigned i=0; i<n; i++)
        cin>>parole[i];

    bool find=false;

    for(unsigned i=0; i<n; i++)
    {
        unsigned j=1;

        while(j<n && find!=true)
        {
            if(s.compare(parole[i]+parole[j])==0 || s.compare(parole[j]+parole[i])==0)
                find=true;
            j++;
        }
    }

    if(find==true)
        cout<<"OK";
    else
    {
        unsigned massimo=parole[0].length();
        unsigned minimo=parole[0].length();

        for(unsigned i=0; i<n; i++)
        {
            if(parole[i].length()>massimo)
                massimo=parole[i].length();

            if(parole[i].length()<minimo)
                minimo=parole[i].length();
        }

        int tmp=0, tmp2=0;
        int c1=0, c2=0;
        for(unsigned i=0; i<n; i++)
        {
            if(parole[i].length()==massimo)
            {
                s1[tmp]=parole[i];
                tmp++;
                c1++;
            }
            else if(parole[i].length()==minimo)
            {
                s2[tmp2]=parole[i];
                tmp2++;
                c2++;
            }
        }

        sort(s1, s1+c1);
        sort(s2, s2+c2);

       

    delete[]parole;
    delete[]s1;
    delete[]s2;

    return 0;
}

Il programma funziona nel primo caso (dove deve stampare "OK"), nel secondo caso gli esempi del testo funzionano bene, ma:
se ad esempio ho le parole "PROVA, esame, BC, ab", mi aspetto in stampa: "esame ab", invece mi stampa "PROVA BC"

DOMANDA:
c'è un modo (o funzione stl) per ordinare le stringhe senza avere problemi con lettere maiuscole e minuscole?
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Sicuro, codice sotto.
Il terzo argument passato a sort è una "Lambda function", niente di spaventoso, semplicemente scrivi lì una funzione e la passi come parametro.
Alternativamente puoi scrivere una funzione da qualche altra parte e passare il pointer alla tua funzione.
Il terzo argument del sort prende una funziona che usa per comparare e decidere se le 2 parole vanno scambiate di posto, percui la Lambda function cattura le 2 string da comparare (by value, quindi copie e non le string originali) ed usa due range-based for loop per cambiare tutti i char dentro la copia delle string in lowercase, percui compari le versioni lowercase delle parole e riordini il vector contenente anche uppercase in base al risultato del paragone tra le parole lowercase.
Se le vuoi riordinate in ordine opposto (come leggendo un dizionario al contrario) allora cambi "return s1 < s2;" in "return s1 > s2;"

CSS:
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    vector<string> parole{ "case", "libro", "Lampada", "setole", "Spento" };
 
    sort(parole.begin(), parole.end(), [](string s1, string s2) {
                                                                    for (auto& e : s1) { e = tolower(e); }
                                                                    for (auto& e : s2) { e = tolower(e); }
                                                                    return s1 < s2;
                                                                    }
    );


    for (auto& e : parole)
    {
        cout << e << " ";
    }
    cout << endl << endl;

    return 0;
}

output:
case Lampada libro setole Spento
 
Ultima modifica:

Svpam

Nuovo Utente
70
2
CPU
intel core i5-2310m
HDD
1TB Western digital 5400rpm
RAM
8gb ddr3
GPU
amd ati 7310m
Monitor
samsung E2220
OS
Windows 7; ubuntu 14.04; Kali linux; debian 7
Sicuro, codice sotto.
Il terzo argument passato a sort è una "Lambda function", niente di spaventoso, semplicemente scrivi lì una funzione e la passi come parametro.
Alternativamente puoi scrivere una funzione da qualche altra parte e passare il pointer alla tua funzione.
Il terzo argument del sort prende una funziona che usa per comparare e decidere se le 2 parole vanno scambiate di posto, percui la Lambda function cattura le 2 string da comparare (by value, quindi copie e non le string originali) ed usa due range-based for loop per cambiare tutti i char dentro la copia delle string in lowercase, percui compari le versioni lowercase delle parole e riordini il vector contenente anche uppercase in base al risultato del paragone tra le parole lowercase.
Se le vuoi riordinate in ordine opposto (come leggendo un dizionario al contrario) allora cambi "return s1 < s2;" in "return s1 > s2;"

CSS:
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    vector<string> parole{ "case", "libro", "Lampada", "setole", "Spento" };
 
    sort(parole.begin(), parole.end(), [](string s1, string s2) {
                                                                    for (auto& e : s1) { e = tolower(e); }
                                                                    for (auto& e : s2) { e = tolower(e); }
                                                                    return s1 < s2;
                                                                    }
    );


    for (auto& e : parole)
    {
        cout << e << " ";
    }
    cout << endl << endl;

    return 0;
}

output:

Scusami, potresti essere un po' più chiaro, perché non ho capito bene, o meglio, non ho capito proprio. Grazie.
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Scusami, potresti essere un po' più chiaro, perché non ho capito bene, o meglio, non ho capito proprio. Grazie.
Bhe ti rivolgo la stessa domanda xD Spiega cosa non hai capito :)
A volte mettere in parole quello che non hai capito ti aiuta a ragionarci e capirlo, oppure capire con un pò più di precisione cosa non hai capito.
E se non sei in grado di fare quell'esercizio di ragionamento, allora so già di non poterti aiutare,
o in maniera piu onesta, non sono intenzionato a perdere il mio tempo quando l'altra persona mi da l'impressione di non starci mettendo molto di suo in termini di impegno o provare a capire.
(rispondere 2 giorni dopo scrivendo "non ho capito nulla rispiegami tutto da capo" è una grave mancanza di rispetto verso il tempo degli altri, dal mio punto di vista) :sisi:
 
Ultima modifica:

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!