Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用正则表达式和Java计算文本中的音节_Java_Arrays_Regex_String - Fatal编程技术网

如何使用正则表达式和Java计算文本中的音节

如何使用正则表达式和Java计算文本中的音节,java,arrays,regex,string,Java,Arrays,Regex,String,我将文本作为字符串,需要计算每个单词的音节数。我尝试将所有文本拆分为单词数组,然后分别处理每个单词。我用了正则表达式。但音节的模式并没有发挥应有的作用。请建议如何更改它以计算正确的音节数。我的初始代码 public int getNumSyllables() { String[] words = getText().toLowerCase().split("[a-zA-Z]+"); int count=0; List <String> tokens = new

我将文本作为
字符串
,需要计算每个单词的音节数。我尝试将所有文本拆分为单词数组,然后分别处理每个单词。我用了正则表达式。但音节的模式并没有发挥应有的作用。请建议如何更改它以计算正确的音节数。我的初始代码

public int getNumSyllables()
{
    String[] words = getText().toLowerCase().split("[a-zA-Z]+");
    int count=0;
    List <String> tokens = new ArrayList<String>();
    for(String word: words){
            tokens = Arrays.asList(word.split("[bcdfghjklmnpqrstvwxyz]*[aeiou]+[bcdfghjklmnpqrstvwxyz]*"));
            count+= tokens.size();

            }
    return count;
}
public int getNumSyllables()
{
String[]words=getText().toLowerCase().split(“[a-zA-Z]+”);
整数计数=0;
List tokens=new ArrayList();
for(字符串字:字){
令牌=Arrays.asList(word.split(“[bcdfghjklmnpqrstvwxyz]*[aeiou]+[bcdfghjklmnpqrstvwxyz]*”);
count+=tokens.size();
}
返回计数;
}
您的线路

String[] words = getText().toLowerCase().split("[a-zA-Z]+");
正在拆分单词,只返回单词之间的空格!您希望在单词之间的空格上拆分,如下所示:

String[] words = getText().toLowerCase().split("\\s+");

这将为您提供一个单词中的多个音节和元音:

public int getNumVowels(String word) {

    String regexp = "[bcdfghjklmnpqrstvwxz]*[aeiouy]+[bcdfghjklmnpqrstvwxz]*";
    Pattern p = Pattern.compile(regexp);
    Matcher m = p.matcher(word.toLowerCase());

    int count = 0;

    while (m.find()) {
        count++;
    }
    return count;
}
您可以在字符串数组中的每个单词上调用它:

    String[] words = getText().split("\\s+");
    for (String word : words ) {
      System.out.println("Word: " + word + ", vowels: " + getNumVowels(word));
    }

更新:正如freerunner所指出的,计算音节的数量比仅仅计算元音要复杂得多。我们需要考虑像ou、ui、oo、最终的沉默e和其他可能的组合。由于我不是以英语为母语的人,我不确定正确的算法是什么。

您使用的分割方法不正确。这种方法接收分离器。你需要写这样的东西:

String[] words = getText().toLowerCase().split(" ");
但是如果你想计算音节的数量,那么计算元音的数量就足够了:

String input = "text";
Set<Character> vowel = new HashSet<>();
vowel.add('a');
vowel.add('e');
vowel.add('i');
vowel.add('o');
vowel.add('u');

int count = 0;
for (char c : input.toLowerCase().toCharArray()) {
    if (vowel.contains(c)){
        count++;
    }
}

System.out.println("count = " + count);
String input=“text”;
Set元音=新HashSet();
元音。加上('a');
元音。加上('e');
元音。加上('i');
元音。加上('o');
元音。加上('u');
整数计数=0;
for(字符c:input.toLowerCase().toCharArray()){
if(元音包含(c)){
计数++;
}
}
System.out.println(“count=“+count”);

使用user5500105的概念,我开发了以下方法来计算单词中音节的数量。这些规则是:

  • 连续元音按1个音节计算。“ae”“ou”是一个音节

  • Y被认为是元音

  • 如果e是唯一的元音,则结尾的e被视为音节:例如:“the”是一个音节,因为结尾的“e”是唯一的元音,而“there”也是一个音节,因为“e”在结尾,单词中还有另一个元音

     public int countSyllables(String word) {
         ArrayList<String> tokens = new ArrayList<String>();
         String regexp = "[bcdfghjklmnpqrstvwxz]*[aeiouy]+[bcdfghjklmnpqrstvwxz]*";
         Pattern p = Pattern.compile(regexp);
         Matcher m = p.matcher(word.toLowerCase());
    
    
         while (m.find()) {
             tokens.add(m.group());
         }
    
     //check if e is at last and e is not the only vowel or not
         if( tokens.size() > 1 && tokens.get(tokens.size()-1).equals("e")  )
             return tokens.size()-1; // e is at last and not the only vowel so total syllable -1 
         return tokens.size(); 
     }
    
    public int count音节(字符串词){
    ArrayList标记=新的ArrayList();
    字符串regexp=“[bcdfghjklmnpqrstvwxz]*[aeiouy]+[bcdfghjklmnpqrstvwxz]*”;
    Pattern p=Pattern.compile(regexp);
    Matcher m=p.Matcher(word.toLowerCase());
    while(m.find()){
    添加(m.group());
    }
    //检查e是否是最后一个元音,e是否不是唯一的元音
    if(tokens.size()>1&&tokens.get(tokens.size()-1).equals(“e”))
    return tokens.size()-1;//e终于是并且不是唯一的元音,所以总音节-1
    返回tokens.size();
    }
    

    • 这个问题来自UCSD的Java课程,对吗

      我认为你应该为这个问题提供足够的信息,这样就不会让想要提供帮助的人感到困惑。这里我有我自己的解决方案,已经由本地项目的测试用例测试过了,也就是UCSD的OJ

      你在这个问题中遗漏了一些关于音节定义的重要信息事实上,我认为这个问题的关键是如何处理
      e
      例如,假设存在
      te
      的组合。如果你把一个词放在一个词的中间,当然它应该被计算成一个音节;然而,如果它在一个单词的末尾,那么在英语中,
      e
      应该被认为是一个
      无声的e
      ,因此它不应该被认为是一个音节

      就这样。我想用一些伪代码写下我的想法:

        if(last character is e) {
              if(it is silent e at the end of this word) {
                 remove the  silent e;
                 count the rest part as regular;
              } else {
                 count++;
        } else {
              count it as regular;
        }
      }
      
      您可能会发现,我不仅仅使用regex来处理这个问题。事实上我已经考虑过了:这个问题真的只能用正则表达式来解决吗?我的回答是:不,我不这么认为。至少现在,根据UCSD给我们的知识,要做到这一点太难了。正则表达式是一个功能强大的工具,它可以非常快速地映射所需的字符。然而,regex缺少一些功能。再以
      te
      为例,当regex面对
      teate
      这样的单词时,它不会三思而后行(我只是编了这个单词作为例子)。如果我们的正则表达式模式将第一个
      te
      算作音节,那么为什么最后一个
      te
      不算作音节呢

      同时,UCSD在作业文件中也提到了这一点:

      如果你发现自己在做精神体操,用一个单一的正则表达式直接计算音节,这通常表明有一个更简单的解决方案(提示:考虑一个循环的字符——参见下面的下一个提示)。仅仅因为一段代码(例如正则表达式)更短并不意味着它总是更好

      这里的提示是,您应该将这个问题与一些循环结合起来考虑,并与正则表达式相结合

      好的,我现在终于应该显示我的代码了:

      protected int countSyllables(String word)
      {
          // TODO: Implement this method so that you can call it from the 
          // getNumSyllables method in BasicDocument (module 1) and 
          // EfficientDocument (module 2).
          int count = 0;
          word = word.toLowerCase();
      
          if (word.charAt(word.length()-1) == 'e') {
              if (silente(word)){
                  String newword = word.substring(0, word.length()-1);
                  count = count + countit(newword);
              } else {
                  count++;
              }
          } else {
              count = count + countit(word);
          }
          return count;
      }
      
      private int countit(String word) {
          int count = 0;
          Pattern splitter = Pattern.compile("[^aeiouy]*[aeiouy]+");
          Matcher m = splitter.matcher(word);
      
          while (m.find()) {
              count++;
          }
          return count;
      }
      
      private boolean silente(String word) {
          word = word.substring(0, word.length()-1);
      
          Pattern yup = Pattern.compile("[aeiouy]");
          Matcher m = yup.matcher(word);
      
          if (m.find()) {
              return true;
          } else
              return false;
      }
      
      您可能会发现,除了使用给定的方法
      countsyllets
      ,我还创建了另外两个方法
      countit
      silente
      countit
      用于计算单词内部的音节,
      silente
      试图找出这个单词是否以无声的
      e
      结尾。还应该注意的是,
      的定义不是沉默的e
      。例如,<代码> <代码>应考虑<代码>不沉默e < /代码>,而<代码> ATE 被认为是代码>静默e>代码>

      下面是我的代码已经通过测试的状态,来自本地测试用例和UCSD的OJ:

      根据OJ的测试结果:

      附言:应该可以
      public int getNumSyllables()
      {
          return getSyllables(getTokens("[a-zA-Z]+"));
      }
      
      protected List<String> getWordTokens(String word,String pattern)
      {
          ArrayList<String> tokens = new ArrayList<String>();
          Pattern tokSplitter = Pattern.compile(pattern);
          Matcher m = tokSplitter.matcher(word);
      
          while (m.find()) {
              tokens.add(m.group());
          }
      
          return tokens;
      }
      
      private int getSyllables(List<String> tokens)
      {
          int count=0;
      
          for(String word : tokens)
          if(word.toLowerCase().endsWith("e") && getWordTokens(word.toLowerCase().substring(0, word.length()-1), "[aeiouy]+").size() > 0)
              count+=getWordTokens(word.toLowerCase().substring(0, word.length()-1), "[aeiouy]+").size();
          else
              count+=getWordTokens(word.toLowerCase(), "[aeiouy]+").size();
      
          return count;
      }
      
         public static int syllables(String s) {
            final Pattern p = Pattern.compile("([ayeiou]+)");
            final String lowerCase = s.toLowerCase();
            final Matcher m = p.matcher(lowerCase);
            int count = 0;
            while (m.find())
               count++;
      
            if (lowerCase.endsWith("e"))
               count--;
      
            return count < 0 ? 1 : count;
         }
      
      int syllables = 0;
          word = word.toLowerCase();
          if(word.contains("the ")){
              syllables ++;
          }
          String[] split = word.split("e!$|e[?]$|e,|e |e[),]|e$");
      
          ArrayList<String> tokens = new ArrayList<String>();
          Pattern tokSplitter = Pattern.compile("[aeiouy]+");
      
          for (int i = 0; i < split.length; i++) {
              String s = split[i];
              Matcher m = tokSplitter.matcher(s);
      
              while (m.find()) {
                  tokens.add(m.group());
              }
          }
      
          syllables += tokens.size();