Reputation: 209
I am trying to build a function to identify if a an expresson has balanced parenthesis or not.
My problem is that I am getting this error on my functions for the variables opening_index and closing_index :
Error:(3, 30) identifier expected but integer literal found.
var opening_index: Int =-1
Error:(6, 30) identifier expected but integer literal found.
var closing_index: Int =-1
Error:(34, 30) identifier expected but integer literal found.
var opening_index: Int =-1
Error:(37, 30) identifier expected but integer literal found.
var closing_index: Int =-1
I have been googling my error for the last hour without finding any valuable cluses.
Here is my code:
object Test
{
def balance(chars: List[Char]): Boolean=
{
var opening_index: Int =-1
var closing_index: Int =-1
opening_index=chars.indexOf('(')
closing_index=chars.indexOf(')')
if (opening_index ==-1 && closing_index==-1)
{
true
}
if (closing_index>-1 && opening_index>-1)
{
if (closing_index<=opening_index) return(false)
else
{
balance(chars.drop(closing_index).drop(opening_index))
}
}
else
return (false)
}
}
Upvotes: 0
Views: 2928
Reputation: 3474
This can be simplified by just counting how many of each there are and seeing if the numbers match up:
def balance (chars: List[Char]): Boolean = {
val opening = chars.count(_ == '(')
val closing = chars.count(_ == ')')
opening == closing
}
balance(List('(', ')', '(', ')', '(')) //false
balance(List('(', ')', '(', ')')) //true
If you want the balanced parentheses to be in order, you can do it recursively:
def balance(chars: List[Char], open: Int = 0): Boolean = {
if (chars.isEmpty)
open == 0
else if (chars.head == '(')
balance(chars.tail, open + 1)
else if (chars.head == ')' && open > 0)
balance(chars.tail, open - 1)
else
balance(chars.tail, open)
}
val x = "(apple + pear + (banana)))".toList
balance(x) //true
val y = "(()(".toList
balance(y) //false
This goes through every element of the list and adds/subtracts to/from a variable called open
until the list is empty, at which point if open
is 0 it returns true
otherwise it returns false
.
Upvotes: 1
Reputation: 170733
When Scala sees =-1
, it gets tokenized (split) not as =
-1
(as in other languages you may be familiar with), but as =-
1
, since =-
is a perfectly fine identifier in Scala.
Since =
hasn't been seen, the entire Int =- 1
must be a type. By infix notation for types, it's equivalent to =-[Int, 1]
. Except 1
here must be a type. To be a type it should start with an identifier, and that's what the error message is saying. If you fixed that, it would complain about unknown =-
type next.
Upvotes: 1
Reputation: 36229
The tokenizer doesn't know, where a token ends or starts. Use some delimiters, which makes the code more readable for humans too:
object Test {
def balance(chars: List[Char]): Boolean =
{
var opening_index: Int = -1
var closing_index: Int = -1
opening_index=chars.indexOf ('(')
closing_index=chars.indexOf (')')
if (opening_index == -1 && closing_index == -1)
{
true
}
if (closing_index > -1 && opening_index > -1)
{
if (closing_index <= opening_index)
return false
else
balance (chars.drop (closing_index).drop (opening_index))
}
else
return false
}
}
Since you only initialize your vars to reinitialize them directly again, you can easily earn some functional points by declaring them as vals:
def balance (chars: List[Char]): Boolean =
{
val opening_index: Int = chars.indexOf ('(')
val closing_index: Int = chars.indexOf (')')
For recursive calls, you don't have to bother - those generate a new pair of values which don't interfere with those of the calling context.
You might also note, that return statements dont need a function-call-look with parens return (false)
but can be written as return false
, and even the return keyword is most of the time superflous.
object Test {
def balance (chars: List[Char]): Boolean =
{
val opening_index: Int = chars.indexOf ('(')
val closing_index: Int = chars.indexOf (')')
if (opening_index == -1 && closing_index == -1)
{
true // but note the else in the 2nd next line
}
else if (closing_index > -1 && opening_index > -1)
{
if (closing_index <= opening_index)
false
else
balance (chars.drop (closing_index).drop (opening_index))
}
else
false
}
}
Upvotes: 4