如何加快这个Clojure代码?

时间:2016-03-01 07:38:33

标签: regex optimization clojure

我是clojure的初学者。我正在尝试使用clojure来解决这个简单的problem on codechef。下面是我的clojure代码,但是这段代码运行时间太长并且给出了TimeoutException。有人可以帮我优化这段代码,让它运行得更快。

  (defn checkCase [str] 
    (let [len (count str)] 
    (and (> len 1) (re-matches #"[A-Z]+" str)))) 
  (println (count (filter checkCase (.split (read-line) " "))))

注意:由于输入错误,我的程序没有超时。在codechef上输入是自动处理的(可能通过输入重定向。请阅读问题以获取更多详细信息) 谢谢!

6 个答案:

答案 0 :(得分:1)

大多数文本查找练习都是在regexp中练习,这一点没有什么不同。通常很难找到一种更有效的方法,无论哪种编程语言都会超过优秀的正则表达式实现。

在这种情况下,re-seqlook around正则表达式,repetition limiting和多行正则表达式标记(?m)是您的朋友

(defn find-acronyms
  [s]
  (re-seq #"(?m)(?<=\W|^)[A-Z]+(?=\W|$)" s))

(find-acronyms "I like coding and will participate in IOI Then there is ICPC")
=> ("IOI" "ICPC")

让我们剖析正则表达式:

  • (?m)多行标记:允许您在多行上匹配正则表达式,因此无需拆分为多个字符串
  • (?<=\W|^)匹配应遵循非单词字符或(多行)字符串的开头
  • [A-Z]{2,}匹配并发大写字母,最少2个
  • (?=\W|$)匹配后应跟一个非单词字符或(多行)字符串的结尾

答案 1 :(得分:0)

我只能猜测,只要您运行此代码段,它就不会向您的read-line调用提供任何内容。或许它确实如此,但不会发送新行作为最后一件事。所以它等待着。

答案 2 :(得分:0)

(defn checkCase [str]
  (let [len (count str)]
    (and (> len 1) (re-matches #"[A-Z]+" str))))

(defn answer [str]
  (println (count (filter checkCase (.split str " ")))))

所以在REPL:

=> (answer "GGG fff TTT")
;-> 2
;-> nil

答案正在打印到屏幕上。但最好让你的函数返回答案而不是打印出来:

(defn answer [str]
  (count (filter checkCase (.split str " "))))

我所做的就是用(read-line)替换你的(read-line)stdin期待来自char* xmlChunk; // your data will be stored inside char* tagStartBegin = strstr(xmlChunk,"<pty"); char* tagStartEnd = strstr(tagStartBegin,">"); char* value = tagStartEnd+1; // get the end tag char* tagEndBegin = strstr(tagStartEnd,"</pty>"); //end the string here *tagEndBegin = '\0'; // parse your value doSomeThing(value); 的输入并永远等待它 - 或直到你的情况发生超时。

答案 3 :(得分:0)

我不确定这是否是代码的缓慢部分,但是如果它是你可以尝试通过在必要时执行它来分解执行和安全gard非常慢的正则表达式部分。我认为使用AND的当前版本已经做到了。如果没有,你可以尝试做其他事情,比如:

(defn checkCase [^String str]
  (cond 
    (< (.length str) 2) 
      false  
    (re-matches #"[A-Z]+" str) 
      true
    :else
      false))

答案 4 :(得分:0)

也许您可以尝试使用re-seq而不是分割字符串并检查每个项目?因此,您将丢失filter.split和其他函数调用。像这样:

(println (count (re-seq #"\b[A-Z]{2,}?\b" (read-line))))

答案 5 :(得分:0)

您需要提交Java程序。您可以在提交之前在命令行上对其进行测试。您可以但不需要使用重定向符号(<>)。只需输入输入,并在每次输入时看到输入,在键入enter后返回计数。

您将需要一个编译(Ahead Of Time,这意味着包含.class文件)和一个导出的main。只有这样它才能成为Java程序。

实际上,当他们要求Java程序时,他们可能意味着.class文件。您可以使用.class程序运行java文件(我想这是他们的测试运行者所做的)。在测试时将其放在shell或批处理文件中,但只需提交.class文件。