扫描字符串中的某些字符并计算它们

时间:2016-10-21 19:43:20

标签: java null

在我的AP计算机科学课上,我们有一个分配,我需要输入一个字符串(在这种情况下总是一条推文),然后检查它是否符合charlimit,看看它是否是转发,并且然后计算Hashtags和Mentions。我已经想到了所有这一切,但是对于Hashtag或提及被计算,它必须没有空格或者返回它。我目前的解决方案是:

for(int i=0; i < tweetLength; i++) {
  if((tweet.charAt(i) == '@')&&((tweet.charAt(i+1) != 0)||(tweet.charAt(i+1) != 32)||(tweet.charAt(i+1) != 13)) ) {
      countMentions++;

  } if((tweet.charAt(i) == '#')&&((tweet.charAt(i+1) != 0)||(tweet.charAt(i+1) != 32)||(tweet.charAt(i+1) != 13)) ) {
      countHashtags++;

  } if(((tweet.charAt(i) == 'R')||(tweet.charAt(i) == 'r'))&&((tweet.charAt(i + 1) == 'T')||(tweet.charAt(i + 1) == 't'))&&(tweet.charAt(i + 2) == ':')) {
      retweet = true;
  }
}

注意,32,13和0是Space,Return和Null的ascii值(我认为,lol) - 我使用数值希望它能奇迹般地解决我的问题,但唉,它有不

这一切都运行正常,但是当字符串的最后有一个符号或哈希符号时,它会返回错误:

java.lang.StringIndexOutOfBoundsException: String index out of range: 1
        at java.lang.String.charAt(String.java:686)
        at Main.main(Main.java:21)
        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 edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

我知道这是因为它试图读取null,但我无法找到解决方案而且我的老师是“教导”。视频&#34;善良,所以帮助不大。

1 个答案:

答案 0 :(得分:1)

在迭代字符串中的字符时,您需要注意不要超出界限。你可以通过确保char(i)不会失败来实现这一点:

for(int i=0; i < tweetLength; i++)
    {
        if (i + 1 == tweetLength)
        {
            // avoid going out of bounds
            // when i == last char of the string
            break;
        }

        if (tweet.charAt(i) == '@')
            countMentions++;

        if (tweet.charAt(i) == '#')
            countHashtags++;

        if (i + 2 < tweetLength)
        {
            // search for i+2 only when
            // i+2 is not outside of the string
            if (((tweet.charAt(i) == 'R') || (tweet.charAt(i) == 'r')) && 
                    ((tweet.charAt(i + 1) == 'T') || (tweet.charAt(i + 1) == 't')) && 
                    (tweet.charAt(i + 2) == ':'))
            {
                retweet = true;
            }
        }
    }

正如你所看到的,当我们定位在最后一个字符上时,我添加了一个break语句来退出循环。当我们在最后但最后一个角色上时,我们也不会检查“:”。

我希望你能得到这个想法,但仅仅是因为你的代码“工作得很好”。你还有一些你没有测试的极端情况(例如:“a b#c”)它不是一个有效的标签,所以你还需要确保在标签符号后面有一个有效的字母。也许还有其他人喜欢“#@ abc”,但你在某种程度上走在了正确的轨道上,所以我会让你做你的任务而不是为你做。

如果你想更好地理解抛出异常的原因,请查看抛出异常的代码:

public char charAt(int index) {
    if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
}

既然我希望你理解逻辑,那就考虑修改你的

for(int i=0; i < tweetLength - 1; i++)

删除第一个if 。无论如何我们正在做这件事,但只是以一种更复杂的方式,对吗? :)

相关问题