0

コードの一部からエラーが発生します。1行のコードのみを表示します。少なくとも、エラーレポートからそれを引き起こしていると思われる行を表示します。それは:

b = temp(temp.length-1).toInt; //temp is an ArrayBuffer[String]

エラーは次のとおりです。

For input string: "z"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at scala.collection.immutable.StringLike$class.toInt(StringLike.scala:231)
at scala.collection.immutable.StringOps.toInt(StringOps.scala:31)
at Driver$.stringParse$1(Driver.scala:59)
at Driver$.main(Driver.scala:86)
at Driver.main(Driver.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

私の知る限り、これは問題を引き起こしています。不変なので変更できないことはわかっています。しかし、私にはわかりません。私はこれを基にしています

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

上記のコードのようなことをすると、オブジェクト全体が変更されますか?TempはArrayBuffer[String]です。だから私は数字の文字列表現にアクセスしてそれを変換しようとしています。しかしそうすることで、これはそれが何であるかを変え、私が何もするのを妨げますか?

私のすべてのコードを入れることが役立つと思うなら、それを編集することを私に知らせてください、しかしそれはたくさんあり、私は誰にも迷惑をかけたくありません。私がこれを理解するのを手伝ってくれる人に感謝します!

*編集:私のコード(ここでのみ私のエラーを理解するのに役立ちますが、見る必要はありません。どこでこのエラーが発生するのかわかりません)。

私のコードのポイントは、上部にあるこれらの文字列のいずれかを解析することです。1つの文字列にまとめてから、他の2つの記号を読み取ってそれに合わせます。strは問題なく解析されますが、str2で「z」、str3で「y」を読み取ると問題が発生します。ご覧のとおり、問題は、との後ろと繰り返しのときの2番目の文字列にあります。文字列はその形式でなければならないことに注意することも重要です。したがって、「(およびx(およびyz))」のように解析することしかできませんが、より便利にする他の方法では解析できません。

val str = "(and x y)";
val str2 = "(and x (and y z))"; //case with expression on th right side
val str3 = "(and (and x y) z)"; //case with expression ont he left side

var i = 0; //just counter used to loop through the finished parsed array to make a list
//var position = 0; //this is used for when passing it in the parser to start off at zero
var hold = new ArrayBuffer[String]();//finished array should be here

def stringParse ( exp: String, expreshHolder: ArrayBuffer[String] ): ArrayBuffer[String] = { //takes two arguments, string, arraybuffer
    var b = 0; //position of where in the expression String I am currently in
    var temp = expreshHolder; //holder of expressions without parens
    var arrayCounter = 0;
    if(temp.length == 0) 
        b = 0; 
        else {
            b = temp(temp.length-1).toInt;
            temp.remove(temp.length-1); 
            arrayCounter = temp.length;
        } //this sets the position of wherever the string was read last plus removes that check from the end of the ArrayBuffer
     //just counts to make sure an empty spot in the array is there to put in the strings

    if(exp(b) == '(') {
        b = b + 1;

        while(exp(b) == ' '){b = b + 1;} //point of this is to just skip any spaces between paren and start of expression type
        if(exp(b) == 'a') {
            //first create the 'and', 'or', 'not' expression types to figure out 
            temp += exp(b).toString;
            b = b+1; 
            temp(arrayCounter) = temp(arrayCounter) + exp(b).toString; //concatenates the second letter
            b = b+1; 
            temp(arrayCounter) = temp(arrayCounter) + exp(b).toString; //concatenates the last letter for the expression type
            //arrayCounter+=1;
            //this part now takes the symbols and puts them in an array
            b+=1;

            while(exp(b) == ' ') {b+=1;} //just skips any spaces until it reaches the FIRST symbol
            if(exp(b) == '(') { 
                temp += b.toString; 
                temp = stringParse(exp, temp); 
                b = temp(temp.length-1).toInt; 
                temp.remove(temp.length-1); 
                arrayCounter = temp.length-1 
                } else {
                    temp += exp(b).toString; 
                    arrayCounter+=1; b+=1; }

            while(exp(b) == ' ') {b+=1;} //just skips any spaces until it reaches the SECOND symbol
            if(exp(b) == '(') { 
                temp += b.toString;
                temp = stringParse(exp, temp); 
                b = temp(temp.length-1).toInt; 
                temp.remove(temp.length-1); 
                arrayCounter = temp.length-1 
                } else {
                    temp += exp(b).toString; 
                    arrayCounter+=1; 
                    b+=1; 

        } 
    temp;
    } else { var fail = new ArrayBuffer[String]; fail +="failed"; fail;}

}
hold = stringParse(str2, ho );
for(test <- hold) println(test);
4

3 に答える 3

2

何がtemp含まれていますか?Stringあなたのコードは、sに変換できるsが含まれていることを前提としていIntますが、String "z"代わりにそこにあるようです。これにより、エラーが発生します。

scala> "z".toInt
java.lang.NumberFormatException: For input string: "z"
...

tempこれがどのように見えるかを再現したものです:

val temp = ArrayBuffer("1", "2", "z")
temp(temp.length-1).toInt //java.lang.NumberFormatException: For input string: "z"

だから、なぜ一部String "z"が入り込んでいるのかを理解する必要がありますtemp

編集:

tempつまり、 ( )に「式」をtemp += exp(b).toString追加し、インデックス()も追加しますtemp += b.toStringtemp次に、インデックス(b = temp(temp.length-1).toInt)のみを保持すると仮定します。何tempのためにあるのかを決めて、それをその目的のためだけに使う必要があります。

于 2012-04-05T01:44:07.890 に答える
1

いいえ、toIntはオブジェクトを変更しません。オブジェクトを引数として受け取り、整数を返し、オブジェクトはそのままにします。

于 2012-04-05T01:53:21.477 に答える
1

あなたのコードが理解できないので、あなたの質問を理解できません。コードを単純化してみましょう。

まず第一に:式タイプとオペランドのリストを持ついくつかの式があります:

scala> :paste
// Entering paste mode (ctrl-D to finish)

abstract sealed class Operand
case class IdentOperand(name: String) extends Operand { override def toString(): String = name }
case class IntOperand(i: Int) extends Operand  { override def toString(): String = i.toString() }
case class ExprOperand(expr: Expression) extends Operand { override def toString(): String = expr.toString() }
case class Expression(exprType: String, operands: Seq[Operand]) {
  override def toString(): String = operands.mkString("(" + exprType + " ", " ", ")")
}

// Exiting paste mode, now interpreting.

defined class Operand
defined class IdentOperand
defined class IntOperand
defined class ExprOperand
defined class Expression

scala> Expression("and", Seq(IdentOperand("x"), IdentOperand("y")))
res0: Expression = (and x y)

scala> Expression("and", Seq(IdentOperand("x"), ExprOperand(Expression("and", Seq(IdentOperand("y"), IdentOperand("z"))))))
res1: Expression = (and x (and y z))

scala> Expression("and", Seq(ExprOperand(Expression("and", Seq(IdentOperand("x"), IdentOperand("y")))), IdentOperand("z")))
res2: Expression = (and (and x y) z)

次に、文字列をこのタイプの式に解析する必要があります。

scala> import scala.util.parsing.combinator._
import scala.util.parsing.combinator._

scala> object ExspessionParser extends JavaTokenParsers {
     |   override def skipWhitespace = false;
     |
     |   def parseExpr(e: String) = parseAll(expr, e)
     |
     |   def expr: Parser[Expression] = "(" ~> exprType ~ operands <~ ")" ^^ { case exprType ~ operands => Expression(exprType, operands) }
     |   def operands: Parser[Seq[Operand]] = rep(" "~>operand)
     |   def exprType: Parser[String] = "and" | "not" | "or"
     |   def operand: Parser[Operand] = variable | exprOperand
     |   def exprOperand: Parser[ExprOperand] = expr ^^ (ExprOperand( _ ))
     |   def variable: Parser[IdentOperand] = ident ^^ (IdentOperand( _ ))
     | }
defined module ExspessionParser

scala> ExspessionParser.parseExpr("(and x y)")
res3: ExspessionParser.ParseResult[Expression] = [1.10] parsed: (and x y)

scala> ExspessionParser.parseExpr("(and x (and y z))")
res4: ExspessionParser.ParseResult[Expression] = [1.18] parsed: (and x (and y z))

scala> ExspessionParser.parseExpr("(and (and x y) z)")
res5: ExspessionParser.ParseResult[Expression] = [1.18] parsed: (and (and x y) z)

そして今(私があなたのコードを理解している限り)、文字列オペランド(、、)を整数値に置き換える必要がありxます。次の2つのメソッドをクラスに追加しましょう。yzExpression

  def replaceOperands(ints: Seq[Int]): Expression = replaceOperandsInner(ints)._2

  private def replaceOperandsInner(ints: Seq[Int]): (Seq[Int], Expression) = {
    var remainInts = ints
    val replacedOperands = operands.collect{
      case n: IdentOperand =>
        val replacement = remainInts.head
        remainInts = remainInts.tail
        IntOperand(replacement)
      case ExprOperand(e) =>
        val (remain, replaced) = e.replaceOperandsInner(remainInts)
        remainInts = remain
        ExprOperand(replaced)
    }

    (remainInts, Expression(exprType, replacedOperands))
  }

そして今、私たちはこれを行うことができます:

scala> ExspessionParser.parseExpr("(and (and x y) z)").get.replaceOperands(Seq(1, 2, 3))
res7: Expression = (and (and 1 2) 3)

また、文字列形式の整数値がある場合は、最初にそれらを変換するだけです。

scala> Seq("1", "2", "3") map { _.toInt }
res8: Seq[Int] = List(1, 2, 3)
于 2012-04-05T08:17:14.597 に答える