查找存储在HashMap中的字符的索引值

时间:2016-01-17 18:29:37

标签: java collections hashmap

我正在寻找打印相应字符的索引值的次数using HashMap

例如,假设我有String str = "Hello World"。截至目前,该程序通过{d=1, W=1, e=1, r=1, o=2, l=3, H=1}显示字符的出现。

我打算在结果集中实现的目标是{d=[9], o=[4, 6], r=[7], W=[5], H=[0], l=[2, 3, 8], e=[1]} *=[*]代表key=[indexValue]

(在最终的resultSet中不考虑空白字符。)

import java.util.HashMap;
import java.util.Map;

public class ConcordanceOfStrings {

    public static void main(String[] args) {
        String str = "Hello World";

        //code to remove whitespaces        
        String newStr = str.replaceAll(" ", "");

        Map<Character, Integer> numCount = new HashMap<Character, Integer>(Math.min(newStr.length(), 26));

        System.out.println("The count is: ");
        for(int i=0; i<newStr.length(); i++){
                char charAt = newStr.charAt(i); 
                if(!numCount.containsKey(charAt)){  
                    numCount.put(charAt, 1);    
                }
                else{
                    numCount.put(charAt, numCount.get(charAt)+1);
                }
            }
            System.out.println(numCount);
        }
    }

2 个答案:

答案 0 :(得分:3)

你非常接近。现在,您将结果存储在Map<Character, Integer>中,因此每个字符的映射都会显示在字符串中。

要存储字符出现的所有索引,您需要有Map<Character, List<Integer>>:每个字符都将映射到整数列表,这将是出现此字符的索引列表。

在当前的代码中,您只需要调整填充地图的逻辑:

if(!numCount.containsKey(charAt)){  
    numCount.put(charAt, new ArrayList<>(Arrays.asList(i))); // <-- we store a list containing the first index i
    // numCount.put(charAt, 1);
} else{
    numCount.get(charAt).add(i); // <-- we add to the existing list the index i
    // numCount.put(charAt, numCount.get(charAt)+1);
}

在地图不包含字符的情况下,我们使用包含第一个索引i的列表初始化映射。 Arrays.asList(i)会返回一个固定大小的列表,因此我将其包装在另一个ArrayList中。

如果地图已经包含该字符,我们只需要获取当前的索引列表并添加我们刚刚找到的索引。

如果您使用的是Java 8,则可以使用Streams更简单地编写整个代码:

Map<Character, List<Integer>> numCount = 
    IntStream.range(0, str.length())
             .filter(i -> str.charAt(i) != ' ')
             .boxed()
             .collect(Collectors.groupingBy(
                 i -> str.charAt(i),
                 Collectors.mapping(v -> v - 1, Collectors.toList())
             ));

答案 1 :(得分:2)

你需要的不仅仅是地图,你需要像Map&gt;这样的东西。以下是对算法进行修改的示例:

    Map<Character, List<Integer>> positions = new HashMap<>();
    Map<Character, Integer> numCount = new HashMap<Character, Integer>(Math.min(newStr.length(), 26));

    for (int i = 0; i < newStr.length(); i++) {

        char charAt = newStr.charAt(i);
        if (!numCount.containsKey(charAt)) {
            numCount.put(charAt, 1);
        }
        else {
            numCount.put(charAt, numCount.get(charAt) + 1);
        }

        if(!positions.containsKey(charAt)){
            List<Integer> cPosition = new LinkedList<>();
            cPosition.add(i);
            positions.put(charAt, cPosition);
        }
        else{
            List<Integer> cPosition = positions.get(charAt);
            cPosition.add(i);
            //positions.put(charAt, cPosition); because of references there is no need to do this
        }
    }