【问题标题】:How to count multiple string length如何计算多个字符串长度
【发布时间】:2017-05-11 13:54:43
【问题描述】:

我有一个这样的字符串:

嘿,我的名字是 $name$;我有 $years$ 岁,我喜欢玩 $sport$,我住在 $country$!

我想返回地图中 $ 之间每个单词的长度,例如地图应该是:

  • 姓名 -> 4
  • 年 -> 5
  • 运动 -> 5
  • 国家 -> 7

一开始我想在我的函数中进行递归调用,但我没有找到方法吗?

【问题讨论】:

  • 您是在问如何提取字符串$name$$years$等?
  • 不是真的如何提取,而是如何获取这些字符串的长度

标签: java string algorithm


【解决方案1】:

您可以使用PatternMatcher 进行匹配,这将返回所有匹配的实例,然后您可以遍历结果并添加到地图中。

String x = "Hey my name is $name$; I have $years$ years old," + 
           "and I love play $sport$ and I live in $country$ !";
Pattern p = Pattern.compile("\\$\\w+\\$");
Matcher m = p.matcher(x);
Map<String, Integer> map = new LinkedHashMap<>();

while(m.find()) {
  String in = m.group().substring(1,m.group().length()-1);
  map.put(in, in.length());
}

【讨论】:

  • 这仅匹配美元 $a$ 中的单个字符,并且地图将忽略可能不需要的重复项。
  • 而且结果不是nameyears等字,而是Hey my name is ; I have
  • 出人意料的是,结果很奇怪:它缺少一个结果,另一个结果混乱。当我打印我的地图时,结果是:国家 -> 7 运动 -> 5 年 -> 5
  • 对新解决方案的另外 1 个编辑 \\w* 应该是 \\w+
  • @ClementCuvillier 为我打印国家 7,名称 4,运动 5,5 年
【解决方案2】:

你可以使用像

这样的正则表达式

(.).*\1

搜索以相同字符开头和结尾的单词。

【讨论】:

    【解决方案3】:

    请记住,地图不允许重复......如果这对您来说可以,那么使用流和正则表达式您可以得到:

    String x = "Hey my name is $name$; I have $years$ years old, and I love play $sport$ and I live in $country$ !";
    //regex to get the words between $
    Matcher m = Pattern.compile("\\$(.*?)\\$").matcher(x);
    List<String> l = new ArrayList<>();
    //place those matchs in a list
    while (m.find()) {
            l.add(m.group(1));
        }
    System.out.println(l);
    //collect those into a Map
    Map<String, Integer> result = l.stream().collect(Collectors.toMap(q -> q, q -> q.length()));
    
    System.out.println(result);
    

    您的地图可能如下所示:

    {国家=7,姓名=4,运动=5,年数=5}

    【讨论】:

    • 不需要group(1),你可以使用group()
    【解决方案4】:

    你可以使用流。

    public void test() {
        String s = "Hey my name is $name$; I have $years$ years old, and I love play $sport$ and I live in $country$ !";
        // Helps me maintain state of whether we are in a word or not.
        // Use AtomicBoolean as a `final` mutable value.
        final AtomicBoolean inWord = new AtomicBoolean(false);
        // Split on the `$` character and stream it.
        Map<String, Integer> myMap = Arrays.stream(s.split("\\$"))
                // Filter out the non-words (i.e. every other one).
                .filter(w -> inWord.getAndSet(!inWord.get()))
                // Generate the map.
                .collect(Collectors.toMap(w -> w, w -> String::length));
        System.out.println(myMap);
    }
    

    打印:

    {国家=7,姓名=4,运动=5,年数=5}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多