【问题标题】:How do I count the number of unique characters in a string? - Updated如何计算字符串中唯一字符的数量? - 更新
【发布时间】:2014-03-25 21:05:17
【问题描述】:

例如,字符串“abc”应该给出 3 个唯一字符,而字符串“abcccd”应该给出 4 个唯一字符。我不允许在其中使用 Map、HashMap、TreeMap、Set、HashSet、StringBuffer 或 TreeSet。

到目前为止,我正在尝试使用 for 循环,但是当我运行程序时,我不断得到 0 个唯一字符。我是 Java 的新手,所以我真的不知道自己在做什么。

编辑:所以我改变了代码,我得到了一个结果,但它最终比我想要的少 1。我将输入“abc”,结果将显示为“2 个唯一字符”而不是 3 个。为了反驳我把 (uniqueChars + 1) 放在 println 语句中。这是一个很好的修正吗?如果用户什么都不放,它仍然会说有 1 个唯一字符。

更新代码:

    userText = userText.toLowerCase(); // userText is declared earlier in the program 
                                       // as the user's input. Setting this to lowercase 
                                       // so it doesn't say "a" and "A" are two different 
                                       // characters.
    int uniqueChars = 0;
    for (int i = 0; i < lengthText-1; i++) { // lengthText is declared earlier 
                                              // as userText.length();
        if (userText.charAt(i) != userText.charAt(i+1))
            uniqueChars++;
    }
    System.out.println("there are " + (uniqueChars + 1) + " unique characters in your string.");
}

【问题讨论】:

  • 你认为你的 for 循环会运行吗?看看你的终止条件。除此之外,您的逻辑有缺陷,您只是在比较相邻的字符。
  • 循环运行,它只是给了我不正确的答案。如果我输入“abc”,程序会返回 0 个唯一字符而不是 3。我还尝试将“i

标签: java count character unique


【解决方案1】:

这个怎么样?这是一个正则表达式解决方案,而不是一个循环:

public static int countUniqueCharacters(String input)
{
    String unique = input.replaceAll("(.)(?=.*?\\1)", "");
    return unique.length();
}

如果程序需要不区分大小写,你可以改用这个:

public static int countUniqueCharacters(String input)
{
    String unique = input.replaceAll("(?i)(.)(?=.*?\\1)", "");
    return unique.length();
}

您可以使用 return input.replaceAll(...).length(); 将其设为单行方法

正则表达式解释:

  • . 匹配任意字符
  • (...) 创建一个捕获组,稍后引用
  • (?=...) 创建一个前瞻,在输入中前瞻
  • .*? 匹配字符与其匹配之间的任何内容(非贪婪匹配)
  • \\1 匹配第一个捕获组
  • (?i) 设置不区分大小写的标志

因此,正则表达式将在字符串后面查找任何重复的字符,然后replaceAll 将用空字符串替换它。所以,像"cabbacbdbadbcabdaadcb" 这样的输入变成"adcb"(保留每个唯一字符的最后一个)。然后,对于包含唯一字符的字符串,该字符串的长度就是答案。

如果出于某种原因,您需要唯一字符串 并且 您需要按原始顺序使用它,则必须先反转原始字符串,然后再去除重复字符(然后将其反转完成后再次)。这将需要第三方库 StringBuffer 或循环。

【讨论】:

    【解决方案2】:

    这是我想出的:

    public static int countUniqueCharacters(String s) {
        String lowerCase = s.toLowerCase();
        char characters[] = lowerCase.toCharArray();
        int countOfUniqueChars = s.length();
        for (int i = 0; i < characters.length; i++) {
            if (i != lowerCase.indexOf(characters[i])) {
                countOfUniqueChars--;
            }
        }
        return countOfUniqueChars;
    }
    

    我只是检查每个字符的索引,如果它与原始索引不同,则会出现多次。

    【讨论】:

    • 您的答案有效!因此,您最初将唯一字符数设为长度并将字符串设为小写。然后,如果该字符出现多次,则从唯一字符数中减去多次出现的次数。谢谢!!
    • 如果 String s = "abcbc";您的方法将返回 3 而不是 1 对吗? Bcoz indexOf() 始终返回此字符串中第一次出现指定字符的索引。因此,对于第一次出现,它不会检测到稍后在字符串中出现的重复字符
    • @src3369 是的,没错。
    • @Veluria:正是我的意思,这个解决方案不起作用,因为即使字符串后面有重复,它也会将第一次出现的 char 视为唯一
    • @src3369 但这是有意的。再次阅读原帖。
    【解决方案3】:

    您可以创建一个新的String,称为uniqueChars,并将其初始化为""。遍历您正在检查的 String 中的字符。如果uniqueChars.contains(charToCheck)false,则将该字符附加到uniqueChars。在循环结束时,uniqueChars.length() 会告诉你有多少个独特的字符。它丑陋且效率低下,但它应该可以工作。

    【讨论】:

      【解决方案4】:

      使用ArrayList 并添加一个字符(如果还没有的话):

      list = new ArrayList<String>();
      for ( /*   */ ) {  // same for loop you wrote
            String character = (String) text.charAt(i);
      
             if(!list.contains(character)) {  // note the '!'
                  list.add(character);
             }
      }
      
      // and finally
      int quantity = list.size();
      

      【讨论】:

        【解决方案5】:

        以下是如何写入文件、如何读取同一个文件以及如何计算特定字符重复次数的程序:

        package filereadexple;
        import java.io.File;
        import java.io.FileInputStream;
        import java.io.FileWriter;
        
                /*
                 * This is a program here I am creating a file by using "filewriter" 
                 * and it is named as count.char and I am reading a same file and 
                 * then how count number of times the particular character repeated.
                 */
        
        public class CountNoOfPartChar {
        
            public static void main (String args[]){
        
                File file = new File ("count.char");
        
                try{
                    FileWriter fw = new FileWriter("count.char");
                    fw.write("In Xanadu did Kubla Khan");
                    fw.write("\r\n");
                    fw.write("A stately pleasure-dome decree:");
                    fw.write("\r\n");
                    fw.write("Where Alph, the sacred river, ran");
                    fw.write("\r\n");
                    fw.write("Through caverns measureless to man");
                    fw.write("\r\n");
                    fw.write("Down to a sunless sea.");
                    fw.close();
                    FileInputStream fis = new FileInputStream(file);
                    int i;
                    int occurs = 0;
                    char current;
                    while ((i=fis.available()) > 0){
                        current = (char)fis.read();
                        if(current == 'a'){
                            occurs++;
                        }
                    }
                    System.out.println("The number of particular character repeated is : " + occurs);
                }
                catch (Exception e){
                    System.out.println(e.getMessage());
                }
            }
        }
        

        【讨论】:

          【解决方案6】:

          如何将其放入数组中,按字母顺序排序,然后应用您的逻辑(比较相邻项)?

          v  = sort(v);//your sort method
          
          int count = 0;
          for (int i = 0;i< lengthText-1; i++) 
          { if v[i] == v[i + 1]  {
                  i++;
              } else {
                  count++;
              }
          }
          

          顺便说一句,您的程序无法运行,因为您在 for 循环中执行了 i == lengthText-1

          【讨论】:

            【解决方案7】:

            与@Alexandre Santos 的逻辑相同,但具有工作示例代码。复杂度为 O(N)。 仅适用于没有空格、数字或特殊字符的字母字符串。

            这也可以用作counting sort

            public class CountChars 
            {
                public static int countUniqCharacters(String str) {
                    int[] counts = new int['z' - 'a' + 1];
                    char[] arr = str.toLowerCase().toCharArray();
            
                    for (char c: arr) {
                        counts[c - 'a']++;
                    }
            
                    int unique = 0;
                    for (int i: counts) {
                        if (i > 0)
                            unique++;
                    }
            
                    return unique;
                }
            
                public static void main(String[] args) {
                    System.out.println("Unique char in " + args[0] 
                            + " is " + CountChars.countUniqCharacters(args[0]));
                }
            }
            

            【讨论】:

              【解决方案8】:
              public class CharacterCount {
                  public static void main(String[] args) {
                      String s = "aaabbbcccddd";
                      String t="";
                      int count = 0;
              
                      //Loop to find unique characters in a string and add it to new string called t
                      //if a character is not found in a string indexOf returns -1
                      for (int i = 0; i < s.length(); i++) {
                          if (t.indexOf(s.charAt(i))==-1) t+=s.charAt(i);
                      }
              
                      //For every character new string t , loop though s find the count and display
                      for (int i = 0; i < t.length(); i++) {
                          count = 0;
                          for (int j = 0; j < s.length(); j++) {
                              if (t.charAt(i) == s.charAt(j)) count++;
                          }
                          System.out.println(t.charAt(i) + " " + count);
                      }
                  }
              }
              

              【讨论】:

                【解决方案9】:
                      public class Main {
                     public static void main(String[] args) {
                   Scanner sc = new Scanner(System.in);
                String s1 = sc.nextLine();
                getvalues(s1);
                   }
                         public static void getvalues(String s1) {
                String s2 = s1.toLowerCase();
                StringBuffer sb = new StringBuffer(s2);
                int l = sb.length();
                int count = 0;
                for (int i = 0; i < l; i++) {
                  count = 0;
                  for (int j = i + 1; j < l; j++) {
                    if (sb.charAt(i) == sb.charAt(j)) {
                      sb.deleteCharAt(j);
                      count++;
                      j--;
                      l--;
                    }
                  }
                  if (count > 0) {
                    sb.deleteCharAt(i);
                    i--;
                    l--;
                  }
                }
                if (sb.length() == 0) {
                  System.out.println(-1);
                } else
                  System.out.println(sb.length());
                 }
                 }
                

                【讨论】:

                  【解决方案10】:

                  使用向量。

                      char[] letters = new char[26];
                      for (char c : letters)
                      {
                          letters[c]=0;
                      }
                  

                  然后对于找到的每个字母,增加向量中的位置。如果任何条目的计数器大于 1,则您有重复

                  【讨论】:

                  • 这将如何工作?一个字符的值通常在 65-122 的范围内,这个数组没有这个位置。
                  • @Aru,使用c - 'A'(或任何被认为适合所需结果的东西)作为索引。但是,数组需要大于 26 个元素,除非只使用字母并且检查不区分大小写/保证输入是一种情况。由于对字符串中允许的内容的限制为零,数组大小必须为 65535(如果程序不区分大小写,则减去 26)。
                  • 其实贴出来的具体循环是要反复设置letters[0]'\0'。您需要使用普通的for 循环来初始化默认值(尽管这不是必需的,因为char 是原始类型)。将数组设为 int[] 会更好地计算重复项,如果只需要不同字母的数量,则将数组设为 boolean[]
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-07-08
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-07-27
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多