【问题标题】:What's the most efficient way to find the length of the longest item in a list?查找列表中最长项目长度的最有效方法是什么?
【发布时间】:2009-03-02 20:31:11
【问题描述】:

给定一个不同长度的单词列表,找到任何单词的最大长度的最佳方法是什么?

例如,下面应该返回 6

findMaxLen("a,set,of,random,words")


当然,这样做很简单……

<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>


或者,短一点……

<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>


但是有没有更好的方法——更有效的方法?

也许是一些 Java 方法?转换为数组并按项目长度排序?计算逗号之间的最大间隔?


实际上,以上两个示例中的任何一个都可以很好地满足我当前的需求,而且这不适用于对性能至关重要的东西,所以我不需要 回答这个问题,但我认为看看人们可能会想出什么仍然很有趣......

【问题讨论】:

  • 此时我只需要插话:基于 xml 的语言是可憎的 :)
  • CFML 是基于标签的,not 基于 XML。除了上面的 cffunction 标记之外的所有标记都会有一个 XML 解析器抱怨。

标签: string language-agnostic list coldfusion code-golf


【解决方案1】:

计算逗号之间的距离。

我认为没有什么比这更快了;它是O(n),并且您必须至少查看每个字符一次(看看它是否是逗号)。

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;
}

或者我想你可以说

"a,set,of,random,words".Split(',').Max(w=>w.Length);

如果我们在玩游戏... ;]

【讨论】:

  • @sfossen:为什么,你不能自己做吗? ;-)
  • 我也可以,但我也不希望我的答案被接受。但是,真的,我可以。诚实。
  • 小错误,lastComma 仅在最长匹配时更新。应该低于第二个 if。
【解决方案2】:

在 Perl 中(假设我们有一个变量 $max 来存储答案):

(length $1 > $max) && ($max = length $1) while "a,set,of,random,words" =~ /(\w+)/g;

或者:

(length $_ > $max) && ($max = length $_) foreach split /,/, "a,set,of,random,words";

或者:

$max = length((sort { length $b <=> length $a } split /,/, "a,set,of,random,words")[0]);

毕竟,TMTOWTDI。

编辑:我忘了核心模块!

use List::Util 'reduce';
$max = length reduce { length $a > length $b ? $a : $b } split /,/, "a,set,of,random,words";

...不知何故设法比其他的更长。哦,好吧!

编辑2:我只记得map()

use List::Util 'max';
$max = max map length, split /,/, "a,set,of,random,words";

更像我正在寻找的。​​p>

编辑 3:为了完整性:

($max) = sort { $b <=> $a } map length, split /,/, "a,set,of,random,words";

【讨论】:

  • 我只想指出,可能有更好的方法来做这些,但我想我会继续把它们拿出来。
【解决方案3】:

看到有code-golf标签,这里是C#中的52个字符

"a,set,of,random,words".Split(',').Max(w=>w.Length);

【讨论】:

  • 我猜我们俩都想同时删除String.
【解决方案4】:

这是“短”CFML 方式 - 72 个字符...

Len(ArrayMax("a,set,of,random,words".replaceAll('[^,]','1').split(',')))

另一个版本,78 个字符,但处理巨大的字符串(参见 cmets)...

Len(ListLast(ListSort("a,set,of,random,words".replaceAll('[^,]','1'),'text')))

【讨论】:

  • 72,如果你使用“set”而不是“series”
  • 糟糕,应该有 c&p-ed 而不是重新输入。塔。
  • 我对CFML一无所知;这适用于任何长度的字符串吗? (例如,没有逗号的 1000 长度字符串)我想知道 ArrayMax 是否真的将 111s 转换为数字数据类型...
  • 你是对的 - ArrayMax 给出了最大数字,因此它将每个字符串转换为一个数字,并且在 300 到 400 之间的某个地方失败。一个类似的基于列表的排序版本(上面添加)可以处理大值,如果非常慢 - 在大约 6.6 秒内完成 10,000,006。
  • (为了比较,问题中的两个原始函数在~60-125ms内处理了相同的10M)
【解决方案5】:

我确实看到了代码 Golf 标签 - 这是 Python 中的 54 个字符:

len(max("a,set,of,random,words".split(","), key=len))

【讨论】:

  • 试试 max(map(len,"a,set,of,random,words".split(","))) 52
  • 至少在字符意义上不一定意味着它,但足够公平。 :) 您可以通过删除键前的空格来保存字符吗?
  • 实际上,@recursive 是 48 个字符。 :-)
  • @recursive - 你打败了我 - 非常好!
【解决方案6】:

在没有字符串额外函数的java中。 (只是一个伪链表:P)在开始时将最大值设为 0

   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;
    }

编辑:刚刚注意到它现在给出的是一个单词字符串而不是字符串列表,没关系在这里保持不变:)

【讨论】:

  • Java 没有以 null 结尾的字符串; charAt 将改为抛出 IndexOutOfBoundsException。尝试改为 s.length()。
  • 本来不想用字符串函数的话会失去乐趣,然后有点混c
【解决方案7】:

如果您不担心可读性... ;)

String longest(String...ss){String _="";for(String s:ss)if(_.length()<s.length())_=s;return _;}

【讨论】:

    【解决方案8】:

    我想这取决于高效的含义。如果这意味着编写的代码中的字符最少,那是一回事。如果这意味着,最少的内存或最快的执行,那就是另一个。

    为了最快的执行,我将使用循环。

    【讨论】:

      【解决方案9】:

      在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;
      }
      

      【讨论】:

        【解决方案10】:

        J

        假设装箱字符串列表(L):

        {.\:~>#&.>L
        

        使用 CSV 文件的示例:

        {.\:~;>#&.>readcsv'test.csv'
        

        【讨论】:

        • 短:>./@:(#@>) 例如:>./@:(#@>)'Hello';'world!'
        【解决方案11】:

        在 Scala 中(55 个字符):

        ",set,of,random,words".split(",").:\(0)(_.length max _)
        

        【讨论】:

          【解决方案12】:

          Clojure:49 字节。

          (def l #(reduce max(for[x(.split%%2)](count x))))
          

          易读版本:

          (defn longest [astr sep]
            (reduce max
              (for [word (.split astr sep)]
                (count word))))
          

          我还在学习这门语言,所以我很想听听任何改进它的方法。

          【讨论】:

            【解决方案13】:

            我面前没有 Python,所以我无法检查它是否有效,但是...

            def maxlen(x):
                return len(sorted(x.split(), key=lambda y: len(y))[1])
            

            应该做的伎俩。

            【讨论】:

              【解决方案14】:

              这不是最简单的吗?

              <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>
              

              【讨论】:

              • 这个方法已经在原始问题中发布了。您可能错过了[code-golf] 标签(现已弃用)- 249 个字符,包括空格;-)。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-20
              • 1970-01-01
              • 2023-01-21
              • 2021-07-17
              • 1970-01-01
              • 2011-03-22
              相关资源
              最近更新 更多