Java程序打印一个仅在字符串中一次可用的字符

时间:2018-09-25 16:26:03

标签: java arrays string search

我正在尝试从字符串中打印字符,该字符在字符串中仅出现一次。这是我正在使用的代码,但答案始终显示为H。

我该如何解决?

class StringRepeat {

    static int i,j;

    public static void main(String[] args) {
        String s1 = "How are How";
        outer:for(i=0;i<=s1.length(); i++)
        {
            inner:for(j=1;j<s1.length(); j++)
            {
              if (s1.charAt(i) != s1.charAt(j))
                break outer;
            }
        }
        System.out.println(s1.charAt(i));
    }
}

4 个答案:

答案 0 :(得分:1)

基本上,您可以通过两种方法解决此问题-蛮力(使用数组)和更智能(使用地图)。

蛮力之路

对于输入字符串中的每个字符,请检查其是否与其他字符相同:

public void uniqueCharsBruteForce(String input) {
    for (int i = 0; i < input.length(); ++i) {
        char candidate = input.charAt(i);
        if (!contains(input, candidate, i)) {
            System.out.println(candidate);
        }
    }
}

private boolean contains(String input, char candidate, int skipIndex) {
    for (int i = 0; i < input.length(); ++i) {
        if (i == skipIndex) {
            continue;
        }
        if (candidate == input.charAt(i)) {
            return true;
        }
    }
    return false;
}

代码很简单但很慢,因此仅用于短字符串。时间复杂度为O(n^2)

使用地图

遍历输入时,计算每个字符出现的次数。最后,仅打印仅出现一次的内容:

public void uniqueCharsBetter(String input) {
    Map<Character, Integer> occurences = new HashMap<>();
    for (int i = 0; i < input.length(); ++i) {
        Character key = Character.valueOf(input.charAt(i));
        occurences.put(key, occurences.getOrDefault(key, 0) + 1);
    }
    occurences.entrySet().forEach(entry -> {
        if (entry.getValue().intValue() == 1) {
            System.out.println(entry.getKey());
        }
    });
}

这可以进一步优化,但有可能满足您的要求。时间复杂度为O(n)

答案 1 :(得分:0)

尝试一下

String s = inputString.toLowerCase();

boolean[] characters = new boolean[26];
for(int i = 0; i < 26; i++)
    characters[i] = true;

for(int i = 0; i < s.length(); i++)
{
    if(characters[s.charAt(i) - 'a'])
    {
        System.out.println(s.charAt(i));
        characters[s.charAt(i) - 'a'] = false;
    }
}

希望这会有所帮助。我假设您将小写字母和大写字母视为相同,否则您可以进行相应的修改

答案 2 :(得分:0)

  1. 如果没有唯一值,这将给出StringIndexOutOfBoundsException 找到了字符:

    outer:for(i=0;i<=s1.length(); i++)
    

    替换为

    int i = 0;
    outer: for(;i<s1.length(); i++)
    
  2. 不需要内部标签,您需要开始搜索 从0开始,而不是1,所以替换

    inner:for(j=1;j<s1.length(); j++)
    

    使用

    for(int j=0;j<s1.length(); j++)
    
  3. 您已经颠倒了测验。如果ij处的字符是 同样,您需要继续外循环。另外,您需要 确保您在i==j时不进行比较。因此您的测试从以下更改:

    if (s1.charAt(i) != s1.charAt(j))
      break outer;
    

    if (i!=j && s1.charAt(i) == s1.charAt(j))
      continue outer;
    
  4. 如果内部for循环终止,即到达 字符串,则i处的字符是唯一的,因此我们需要进行分 的外循环。

  5. 退出外部循环时,需要确定是否找到了唯一元素,如果i < s1.length()就是这种情况。

将所有内容放在一起,我们得到:

String s1= "How are How";
int i = 0;
outer: for(;i<s1.length(); i++)
{
    for(int j=0;j<s1.length(); j++)
    {
      if (i!=j && s1.charAt(i) == s1.charAt(j))
       continue outer;
    }
    break;
}
if(i<s1.length()) System.out.println(s1.charAt(i));

这里是代码(IDEOne)的链接。

答案 3 :(得分:0)

这将打印出在文本中仅出现一次的每个字符。

final String s1 = "How are How";
outer:for(int i = 0; i < s1.length(); i++)
{
    for(int j = 0; j < s1.length(); j++)
    {
        if(s1.charAt(i) == s1.charAt(j) && i != j)
        {
            continue outer;
        }
    }
    System.out.println(s1.charAt(i);
}