【问题标题】:Print stars(*) under the characters of string in java在java中字符串的字符下打印星(*)
【发布时间】:2015-10-02 15:24:03
【问题描述】:

我在面试中被问到了一个 java 问题。打印字符串中的不同字符并在每个字符下打印星号 (*),以显示该字符在该字符串中重复了多少次。

例如:我的字符串是“GOOGLE”,那么输出应该是

G O L E
* * * *
* *

我在 java 中尝试过,我能够创建一个 HashMap,它将字符和重复次数存储在字符串中。但是HashMap不是基于字符串的插入顺序。我也不知道下一步应该是什么。有人能帮我吗?提前致谢

public void myFunction(String str) {
    int length = str.length();
    HashMap<Character, Integer> hm = new HashMap<>();
    for(int i=0;i<length;i++){
        char ch = str.charAt(i);
        if(hm.containsKey(ch)){
            hm.put(ch, hm.get(ch)+1);               
        }
        else {
            hm.put(ch, 1);
        }


    }
        System.out.println(hm);
}

OUTPUT - Enter a String: 
GOOGLE
{E=1, G=2, L=1, O=2}

【问题讨论】:

  • 你可以在这里找到答案:stackoverflow.com/questions/683518/… 特别检查 LinkedHashMap
  • 这样简单的事情没有必要使用HashMap。这是相关的,但有点矫枉过正。一个包含 3 行代码的简单一维数组就可以了。

标签: java string collections hashmap


【解决方案1】:

如果您使用LinkedHashMap,它将保持插入顺序。你可以做这样的事情。还要添加一个max 变量,因为我们稍后会在打印时需要它。

String input = "GOOGLE";
int max = 0;
LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
for (char c: input.toCharArray()){
    if (map.containsKey(c)){
        map.put(c, map.get(c) + 1);
    }else{
        map.put(c, 1);
    }
    max = Math.max(max, map.get(c));
}
System.out.println(map);

输出:

{G=2, O=2, L=1, E=1}

然后只需遍历您必须打印的行数并遍历每个字符。像这样的东西应该可以解决问题。

for (int i=0; i<=max; i++){
    for (char c: map.keySet()){
        if (i==0){
            System.out.print(c);
        }else if (i<= map.get(c)){
            System.out.print("*");
        }else{
            System.out.print(" ");
        }
    }
    System.out.println();
}

输出:

GOLE
****
** 

【讨论】:

    【解决方案2】:

    这是一个好的开始。

    接下来我要做的是将HashMap 更改为LinkedHashMap,以便我们可以保持字符的顺序并添加long 以了解字符出现的最大次数。因此,我会将您当前的代码更改为:

    public void myFunction(String str) {
    int length = str.length();
    long maxOcurrences = 0;
    LinkedHashMap<Character, Integer> hm = new LinkedHashMap<>();
    for(int i=0;i<length;i++){
        char ch = str.charAt(i);
        long nextValue;
        if(hm.containsKey(ch)){
            nextValue = hm.get(ch)+1
            hm.put(ch, nextValue);               
        }
        else {
            nextValue = 1;
            hm.put(ch, nextValue);
        }
    
        if(nextValue > maxOcurrences)
        {maxOcurrences = nextValue;}
    
    
    }
        System.out.println(hm);
    }
    

    接下来我将通过遍历LinkedHashMap 来按顺序打印字符。比如:

    for (Map.Entry<Character, Integer> entry : hm.entrySet()) {
        System.out.print(entry.getKey());
    }
    System.out.println();
    

    最后,我将创建一个循环,迭代maxOcurrences 次并在需要时打印*

    for(int i = 0; i < maxOcurrences; i++)
    {
        //Iterate over each character again
        for (Map.Entry<Character, Integer> entry : hm.entrySet()) {
            if(entry.getValue() > i)
            {
                //Print Star
                System.out.print("*");
            }else{
                //Print space
                System.out.print(" ");
            }
            System.out.println();
        }
    }
    

    【讨论】:

    • 您可以在遍历键时捕获第一行的大小写。这样,您只需遍历地图一次。
    • @gonzo 感谢您的意见!确实如此,但区别并没有那么大,ifs 的 CPU 成本往往比没有 ifs 的额外循环的 CPU 成本更高。
    猜你喜欢
    • 2015-06-19
    • 2021-11-09
    • 2017-04-15
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多