You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何妥善保留println调试代码?

Great question—dealing with leftover debug prints is such a common annoyance, especially for small scripts where setting up a full test suite feels overkill. Your two-file approach works, but there are cleaner ways to keep your debug work without duplicating code or adding heavy tools. Here are a few Scala-specific solutions tailored to your use case:


1. Custom Debug Toggle (Simplest for Small Programs)

Create a tiny utility object to wrap your debug prints, so you can flip a single switch to enable/disable all debug output. This avoids cluttering your code with repeated conditionals and keeps your debug logic centralized.

Here's how to adapt your code:

import java.io.PrintWriter
import scala.collection.mutable.ListBuffer
import scala.collection.mutable.{Set => MutSet}
import scala.collection.mutable.{Map => MutableMap}
import scala.collection.mutable.{ListBuffer}

// Add this debug utility at the top
object Debug {
  var enabled: Boolean = false // Flip this to true/false to toggle debug
  def println(msg: => String): Unit = {
    if (enabled) scala.Predef.println(msg)
  }
}

object Solution {
  /** @TODO "Sherlock and the Valid String", Strings */
  // Complete the isValid function below.
  def isValid(s: String): String = {
    // Count frequencies
    var freqmap = Map[Char, Int]()
    var old = 0
    for (c <- s) {
      old = freqmap.getOrElse(c, 0) + 1
      freqmap = freqmap + (c -> old)
    }
    // Replace println with Debug.println
    Debug.println(s"Counts of characters in string:\n" + freqmap.mkString(", \n"))
    // Check if problems or okay
    var oneDeviation = false
    var initFreq = freqmap(s(0))
    val allowedFreqs = ListBuffer(initFreq)
    val counter = MutableMap[Int, Int](initFreq -> 1)
    var isFreqOne = false
    var freqThatIsOne: FreqIsOne = None
    Debug.println(s"Init freq: $initFreq")
    Debug.println(s"counter: " + counter.mkString(", \n"))
    Debug.println()
    for (freq <- freqmap.values) {
      Debug.println("------------------")
      Debug.println(s"Freq: $freq")
      if (!oneDeviation) {
        if (freq != initFreq) {
          oneDeviation = true
          // greater than 1 diff and no freq is 1 , eg 2 and 4
          // if pass this we know diff is 1
          if (isBiggerThanOneDiffAndNoOneFreq(initFreq, freq)) {
            return "NO"
          }
          // check if we have a freq that is one
          if (initFreq == 1 || freq == 1) {
            // one freq which is 1
            if (initFreq == 1) {
              isFreqOne = true
              freqThatIsOne = Init
              // only freq allowed
              allowedFreqs.remove(0)
              allowedFreqs += freq
            } else if (freq == 1) {
              isFreqOne = true
              freqThatIsOne = Freq
              // only allowed is initFreq
            }
            // one diff but larger than 1 freqs, only allowed
            // is the lower frequency
          } else {
            if (freq > initFreq) {
              allowedFreqs.remove(0)
              allowedFreqs += freq
            }
          }
          // no new freq
        } else {
        }
      } else {
        if (!allowedFreqs.contains(freq)) return "NO"
      }
      old = counter(initFreq)
      counter(initFreq) = old + 1
      Debug.println(s"counter: " + counter.mkString(", "))
    }
    "YES"
  }
  def isBiggerThanOneDiffAndNoOneFreq(initFreq: Int, freq: Int): Boolean = {
    math.abs(freq - initFreq) > 1 && (initFreq != 1 && freq != 1)
  }
  sealed trait FreqIsOne
  case object Init extends FreqIsOne
  case object Freq extends FreqIsOne
  case object None extends FreqIsOne
  def main(args: Array[String]) {
    val stdin = scala.io.StdIn
    val s = stdin.readLine
    // Enable debug here if needed
    // Debug.enabled = true
    val result = isValid(s)
    println(result)
  }
}

Just uncomment Debug.enabled = true in main when you need to see debug output, and comment it out for clean production runs. No duplicate files needed!


2. Command-Line Toggle (No Code Changes Needed)

If you don't want to edit code to enable debug, use system properties to control output at runtime. Wrap your debug prints in a check for a system property:

// Replace your println calls with this:
if (sys.props.getOrElse("debug", "false").toBoolean) {
  println(s"Counts of characters in string:\n" + freqmap.mkString(", \n"))
}

Then run your program with debug enabled like this:

scala -Ddebug=true Solution.scala

And run normally without the -Ddebug=true flag to suppress output. This is great for quick debugging without touching your code.


3. Lightweight Logging (More Flexible for Growth)

If you want to scale beyond simple prints (like different debug levels), use a minimal logging library like slf4j-simple—no complex configuration required.

First, add the dependency (if using sbt, add to build.sbt):

libraryDependencies += "org.slf4j" % "slf4j-simple" % "2.0.9"

Then replace your println calls with debug logs:

import org.slf4j.LoggerFactory

object Solution {
  private val logger = LoggerFactory.getLogger(getClass)
  
  def isValid(s: String): String = {
    // ... your code ...
    logger.debug(s"Counts of characters in string:\n${freqmap.mkString(", \n")}")
    // ... rest of your code ...
  }
}

By default, debug logs are hidden. To enable them, set the log level via system property:

scala -Dorg.slf4j.simpleLogger.defaultLogLevel=debug Solution.scala

This gives you more control (info, warn, error levels) if your program grows, without the overhead of a full test framework.


Why Your Two-File Approach Isn't Ideal

Keeping separate debug and clean versions works, but it's easy to forget to sync changes between the two files (e.g., fixing a bug in one but not the other). The above solutions let you keep a single codebase while retaining all your debug work.

内容的提问来源于stack exchange,提问作者Databogdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:32:27