Qual è il modo più efficiente per trovare la lunghezza dell'elemento più lungo in un elenco?
-
03-07-2019 - |
Domanda
Dato un elenco di parole di lunghezza assortita, qual è il modo migliore per trovare la lunghezza massima di qualsiasi parola?
Ad esempio, quanto segue dovrebbe restituire 6
findMaxLen("a,set,of,random,words")
Certo, è abbastanza banale farlo ...
<cffunction name="findMaxLen" returntype="Numeric">
<cfset var CurMax = 0 />
<cfset var CurItem = 0 />
<cfloop index="CurItem" list="#Arguments[1]#">
<cfif Len(CurItem) GT CurMax >
<cfset CurMax = Len(CurItem)/>
</cfif>
</cfloop>
<cfreturn CurMax />
</cffunction>
O, un po 'più corto ...
<cffunction name="findMaxLen" returntype="Numeric">
<cfset var CurMax = 0 />
<cfset var CurItem = 0 />
<cfloop index="CurItem" list="#Arguments[1]#">
<cfset CurMax = Max( CurMax , Len(CurItem) ) />
</cfloop>
<cfreturn CurMax />
</cffunction>
Ma c'è un modo migliore: qualcosa di più efficiente?
Forse qualche metodo Java? Conversione in array e ordinamento per lunghezza articolo? Conteggio del divario più grande tra virgole?
In termini pratici, uno dei due esempi precedenti funzionerà perfettamente per le mie esigenze attuali, e questo non è per qualcosa che è critico per le prestazioni, quindi non ho bisogno una risposta a questo , ma ho pensato che sarebbe comunque interessante vedere cosa potrebbe inventare la gente ...
Soluzione
Conta la distanza tra le virgole.
Non credo che nulla potrebbe essere più veloce di così; è O (n)
e devi guardare ogni personaggio almeno una volta (per vedere se è una virgola).
int FindLongestWord(char* str)
{
char* lastComma = str - 1;
int longest = 0;
int length;
char* pCheckChar;
for(pCheckChar = str; *pCheckChar; pCheckChar++)
{
if(*pCheckChar == ',')
{
length = pCheckChar - lastComma - 1;
if(length > longest)
{
longest = length;
}
lastComma = pCheckChar;
}
}
// Check to see if the last word is the longest
length = pCheckChar - lastComma - 1;
if(length > longest)
{
longest = length;
}
return longest;
}
o suppongo che potresti semplicemente dire
"a,set,of,random,words".Split(',').Max(w=>w.Length);
se stiamo giocando ...;]
Altri suggerimenti
In Perl (supponendo che abbiamo una variabile $ max
in cui deve essere memorizzata la risposta):
(length $1 > $max) && ($max = length $1) while "a,set,of,random,words" =~ /(\w+)/g;
o
(length In Perl (supponendo che abbiamo una variabile $ max
in cui deve essere memorizzata la risposta):
(length $1 > $max) && ($max = length $1) while "a,set,of,random,words" =~ /(\w+)/g;
o
$max = length((sort { length $b <=> length $a } split /,/, "a,set,of,random,words")[0]);
o
use List::Util 'reduce';
$max = length reduce { length $a > length $b ? $a : $b } split /,/, "a,set,of,random,words";
TMTOWTDI, dopo tutto.
EDIT: ho dimenticato i moduli principali!
use List::Util 'max';
$max = max map length, split /,/, "a,set,of,random,words";
... che in qualche modo riesce a essere più lungo degli altri. Oh bene!
EDIT 2: ho appena ricordato map ()
:
($max) = sort { $b <=> $a } map length, split /,/, "a,set,of,random,words";
È più simile a quello che sto cercando.
EDIT 3: E solo per completezza:
<*> > $max) && ($max = length In Perl (supponendo che abbiamo una variabile $ max
in cui deve essere memorizzata la risposta):
(length $1 > $max) && ($max = length $1) while "a,set,of,random,words" =~ /(\w+)/g;
o
<*>
o
<*>
TMTOWTDI, dopo tutto.
EDIT: ho dimenticato i moduli principali!
<*>
... che in qualche modo riesce a essere più lungo degli altri. Oh bene!
EDIT 2: ho appena ricordato map ()
:
<*>
È più simile a quello che sto cercando.
EDIT 3: E solo per completezza:
<*>) foreach split /,/, "a,set,of,random,words";
o
<*>TMTOWTDI, dopo tutto.
EDIT: ho dimenticato i moduli principali!
<*>... che in qualche modo riesce a essere più lungo degli altri. Oh bene!
EDIT 2: ho appena ricordato map ()
:
È più simile a quello che sto cercando.
EDIT 3: E solo per completezza:
<*> Visto che c'è un tag code-golf
, ecco 52 caratteri in C #
"a,set,of,random,words".Split(',').Max(w=>w.Length);
Ed ecco il modo 'breve' di CFML - 72 caratteri ...
Len(ArrayMax("a,set,of,random,words".replaceAll('[^,]','1').split(',')))
Un'altra versione, 78 caratteri ma gestisce stringhe enormi (vedi commenti) ...
Len(ListLast(ListSort("a,set,of,random,words".replaceAll('[^,]','1'),'text')))
Ho visto il codice golf tag - qui ci sono 54 caratteri in Python:
len(max("a,set,of,random,words".split(","), key=len))
In java senza funzioni extra di stringa. (solo un elenco pseudo-linkato: P) Dare max come 0 all'inizio
int find(LinkedList strings, int max) {
int i;
String s=(String)strings.element();
for(i=0;s.charAt(i)!='\0';i++);
if(strings.hasNext())
return find(strings.Next(),(i>max?i:max));
return max;
}
Modifica: ho appena notato che ora viene fornita una stringa di parole, non un elenco di stringhe, beh, non importa che rimanga qui lo stesso :)
Se non sei preoccupato per la leggibilità ...;)
String longest(String...ss){String _="";for(String s:ss)if(_.length()<s.length())_=s;return _;}
Immagino che dipenda da ciò che significa efficiente. se significa la minima quantità di caratteri nel codice scritto, questa è una cosa. se significa, meno quantità di memoria o esecuzione più veloce, questo è un altro.
per l'esecuzione più veloce prenderò il ciclo.
in vc ++
int findMaxLen(const char *s)
{
const char c = ',';
int a = 0, b = 0;
while(*s)
{
while(*s && *s++ != c)b++;
if(b > a)a=b;
b = 0;
}
return a;
}
In J
Assumi un elenco di stringhe inscatolate (L):
{.\:~>#&.>L
Un esempio che utilizza un file CSV:
{.\:~;>#&.>readcsv'test.csv'
In scala (55 caratteri):
",set,of,random,words".split(",").:\(0)(_.length max _)
Clojure: 49 byte.
(def l #(reduce max(for[x(.split%%2)](count x))))
Versione leggibile:
(defn longest [astr sep]
(reduce max
(for [word (.split astr sep)]
(count word))))
Sto ancora imparando la lingua, quindi mi piacerebbe sentire qualsiasi modo per migliorarla.
Non ho Python davanti a me, quindi non posso controllare che funzioni, ma ...
def maxlen(x):
return len(sorted(x.split(), key=lambda y: len(y))[1])
Dovrebbe fare il trucco.
Non sarebbe più semplice?
<cffunction name="findMaxLen" returntype="Numeric">
<cfset longest = 0>
<cfloop list="#Arguments[1]#" index="w">
<cfif len(w) gt longest>
<cfset longest = len(w)>
</cfif>
</cfloop>
<cfreturn longest>
</cffunction>