在字符串中查找唯一字符?逻辑上有什么问题。我找不到错误。

huangapple go评论70阅读模式
英文:

Find unique character in a string ? What is wrong in logic . I'm unable to find error

问题

我正在尝试找出字符串中仅出现一次的字符,该字符串只包含字母。

以下是我的代码:

public static void main(String[] args)
{
    int count=0;
    Scanner sc= new Scanner(System.in);
    System.out.println("Enter the string: ");
    String s=sc.nextLine();
    char ch1=s.charAt(0);
    if(s.matches("[A-Za-z]+"))
    {
        for(int i=0;i<s.length();i++)
        {
            System.out.println(s.length());
            System.out.println(ch1);
            for(int j=1;i<s.length();j++)
            {
                if(s.charAt(i)==s.charAt(j))
                {
                    count++;
                }				
            }
            if(count == 1)
            {
                System.out.println(s.charAt(i));
            }
				
        }
    }
    else
        System.out.println("Invalid");	
}

我得到了StringIndexOutOfBoundsException错误。

我做错了什么?

英文:

I am trying to find characters that occur exactly once in a string, where the string contains only letters.

Here's my code:

public static void main(String[] args)
{
	int count=0;
	Scanner sc= new Scanner(System.in);
	System.out.println(&quot;Enter the string: &quot;);
	String s=sc.nextLine();
	char ch1=s.charAt(0);
	if(s.matches(&quot;[A-Za-z]+&quot;))
	{
		for(int i=0;i&lt;s.length();i++)
		{
			System.out.println(s.length());
			System.out.println(ch1);
			for(int j=1;i&lt;s.length();j++)
			{
				if(s.charAt(i)==s.charAt(j))
				{
					count++;
				}				
			}
			if(count == 1)
			{
				System.out.println(s.charAt(i));
			}
				
		}
	}
	else
		System.out.println(&quot;Invalid&quot;);	
}

I'm getting a StringIndexOutOfBoundsException.

What am I doing wrong?

答案1

得分: 1

你忘记在外部循环中在检查第i个字符后将计数变量count重置为0。

for (int i = 0; i < s.length(); i++)
{
    System.out.println(s.length());
    System.out.println(ch1);

    count = 0; //缺少的一行

    for (int j = 1; j < s.length(); j++)
    {
        if (s.charAt(i) == s.charAt(j))
        {
            count++;
        }               
    }
    if (count == 1)
    {
        System.out.println(s.charAt(i));
    }
        
}

没有这一步,它会保留先前检查的字符的计数值,因此不会从零开始(而我们需要从零开始,以便为每个字符检查频率)。

英文:

You are forgetting to set your count variable back to 0 in the outer loop after checking s[i]th character.

for(int i = 0; i &lt; s.length(); i++)
{
    System.out.println(s.length());
    System.out.println(ch1);

    count = 0; //missing line

    for(int j = 1; j &lt; s.length(); j++)
    {
        if(s.charAt(i) == s.charAt(j))
        {
            count++;
        }               
    }
    if(count == 1)
    {
        System.out.println(s.charAt(i));
    }
        
}

Without that, it would store the value of count from previously checked character and so would not start from zero (which is what we have to do to check frequency for each character).

答案2

得分: 1

尝试在第一个循环内部初始化计数器(或者由于在循环外部没有使用,将声明移到循环内部)。你目前的初始化方式(一次性)会在移动到下一个字符时继续增加计数器的值。另外,由于你正在使用1 进行测试,将内部循环的初始化改为0,并将条件改为 j(当前为 i)

import java.util.*;
import java.lang.*;

public class UniqueChar
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the string: ");
        String s = sc.nextLine().toLowerCase(); // 改为小写是个好主意
        char ch1 = s.charAt(0);

        if (s.matches("[A-Za-z]+"))
        {
            for (int i = 0; i < s.length(); i++)
            {
                int count = 0; // 在这里初始化
                System.out.println(s.length());
                System.out.println(ch1);

               for (int j = 0; j < s.length(); j++) // 将初始化改为 0,条件改为 j
                {
                    if (s.charAt(i) == s.charAt(j))
                    {
                        count++;
                    }               
                }
                if (count == 1)
                {
                    System.out.println(s.charAt(i));
                }
                    
            }
        } else {
            System.out.println("Invalid");  
        }
    }
}

另外,将输入转换为统一的大小写是个好主意。目前的设置会将大写字母 A 和小写字母 a 视为不同,除非这是要求(在这种情况下,应该忽略 toLowerCase)。

英文:

Try and initialize counter inside the first loop (Or since its not being used outside the loop, shift the declaration). The way you are initializing it (once) for the entire program will keep on increasing the value even when you move to the next character. Also, since you are testing using 1, change the inner loop initialization to 0 and the condition to j (its currently i)

import java.util.*;
import java.lang.*;

public class UniqueChar
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println(&quot;Enter the string: &quot;);
        String s = sc.nextLine().toLowerCase(); //good idea to change casing
        char ch1 = s.charAt(0);

        if (s.matches(&quot;[A-Za-z]+&quot;))
        {
            for (int i = 0; i &lt; s.length(); i++)
            {
                int count = 0; // initialize here
                System.out.println(s.length());
                System.out.println(ch1);

               for (int j = 0; j &lt; s.length(); j++) // changed initialization to 0 and condition to j
                {
                    if (s.charAt(i) == s.charAt(j))
                    {
                        count++;
                    }               
                }
                if (count == 1)
                {
                    System.out.println(s.charAt(i));
                }
                    
            }
        } else {
            System.out.println(&quot;Invalid&quot;);  
        }
    }
}

Also, its a good idea to change the input to a uniform casing. The current setup will treat A and a as different, unless thats the requirement (in which case you should ignore the toLowerCase).

答案3

得分: 0

除了在每个内部循环开始之前设置count = 0(或者更好的做法是 - 将声明移到循环内部),并在内部循环中将i &lt; s.length()中的i更正为j < s.length()`,这里有一个建议:

如果您期望处理大字符串,您可以通过一次遍历字符串并计算每个字符出现的次数,最后检查哪些字符只出现了一次,从而实现O(n)的解决方案。

英文:

Apart from setting count = 0 before the beginning of each inner loop (or even better - moving the declaration inside the loop) and correcting your typo from i &lt; s.length() to j &lt; s.length() in the inner loop, here's a suggestion:

If you're expecting huge strings, you could implement a O(n) solution by iterating the string just once and counting how many times each character occurred and finally checking which of them occurred once.

答案4

得分: 0

这项任务可以使用Java Stream API来实现:

  • 计算输入字符串中每个字符的频率,将它们收集到一个映射(map)中
  • 过滤映射中频率为1的条目(唯一字符)

示例:

public static void printUnique(String str) {
    str.chars()                            
	   .mapToObj(x -> (char) x)            
	   .collect(Collectors.groupingBy(     
		   x -> x, LinkedHashMap::new, Collectors.counting())) 
	   .entrySet().stream()                
	   .filter(e -> e.getValue() == 1)     
	   .map(Map.Entry::getKey)             
	   .forEach(System.out::print);        
    System.out.println();
}

测试:

printUnique("Hello World");
printUnique("quickbrownfoxjumpsoverthelazydog");

输出:

He Wrd
qickbwnfxjmpsvthlazydg
英文:

This task could be implemented using Java Stream API:

  • calculate frequencies of each character in the input string, collect them into map
  • filter map entries where frequency is 1 (unique character)

Example:

public static void printUnique(String str) {
    str.chars()                            // get IntStream of characters
	   .mapToObj(x -&gt; (char) x)            // convert to stream of Character
	   .collect(Collectors.groupingBy(     // count frequencies using LinkedHashMap to prevent order of insertion
		   x -&gt; x, LinkedHashMap::new, Collectors.counting())) 
	   .entrySet().stream()                // get stream of entries
	   .filter(e -&gt; e.getValue() == 1)     // detect uniques
	   .map(Map.Entry::getKey)             // remap Map.Entry&lt;Character, Long&gt; to character
	   .forEach(System.out::print);        // print in a row
    System.out.println();
}

Test:

printUnique(&quot;Hello World&quot;);
printUnique(&quot;quickbrownfoxjumpsoverthelazydog&quot;);

Output:

He Wrd
qickbwnfxjmpsvthlazydg

huangapple
  • 本文由 发表于 2020年8月16日 15:25:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63434244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定