简体   繁体   English

如何计算字符串中唯一字符的数量? - 更新

[英]How do I count the number of unique characters in a string? - Updated

For example, the string "abc" should give 3 unique characters, while the string "abcccd" would give 4 unique characters. 例如,字符串“abc”应该给出3个唯一字符,而字符串“abcccd”将给出4个唯一字符。 I'm not allowed to use Map, HashMap, TreeMap, Set, HashSet, StringBuffer or TreeSet in this. 我不允许在这里使用Map,HashMap,TreeMap,Set,HashSet,StringBuffer或TreeSet。

So far I'm trying to use a for loop but when I run the program I keep getting 0 unique characters. 到目前为止,我正在尝试使用for循环但是当我运行程序时,我一直得到0个独特的字符。 I'm kind of new at Java so I really have no idea what I'm doing. 我是Java的新手,所以我真的不知道我在做什么。

Edit: so I changed the code around and I'm getting a result but it ends up being 1 less than what I want. 编辑:所以我改变了代码,我得到了一个结果,但它最终比我想要的少1。 I'll type in 'abc' and the result will come up as "2 unique characters" instead of three. 我将输入'abc',结果将显示为“2个唯一字符”而不是3个。 To counter that I put (uniqueChars + 1) in the println statement. 为了反击我在println语句中放置(uniqueChars + 1)。 Is this a good correction? 这是一个很好的修正吗? If the user puts nothing, it will still say that there's 1 unique character. 如果用户什么都不放,它仍然会说有1个唯一的字符。

Updated code: 更新的代码:

    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.");
}

How about this one? 这个怎么样? It's a regex solution rather than a loop: 它是一个正则表达式解决方案而不是循环:

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

If the program needs to be case-insensitive, you can use this instead: 如果程序需要不区分大小写,则可以使用此代码:

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

You could make this a single-line method with return input.replaceAll(...).length(); 你可以使用return input.replaceAll(...).length();

Regex Explained: 正则表达式解释:

  • . matches any character 匹配任何角色
  • (...) creates a capturing group, to be referenced later (...)创建一个捕获组,稍后将引用
  • (?=...) creates a lookahead, to look forwards in the input (?=...)创建一个前瞻,在输入中向前看
  • .*? matches anything between the character and its match (non-greedy matching) 匹配角色及其匹配之间的任何内容(非贪婪匹配)
  • \\\\1 matches the first capturing group \\\\1匹配第一个捕获组
  • (?i) sets the case-insensitive flag (?i)设置不区分大小写的标志

So, the regex will look for any character which has a duplicate later in the string, and then replaceAll will replace it with the empty string. 因此,正则表达式将查找字符串中稍后有重复的任何字符,然后replaceAll将用空字符串替换它。 So, an input like "cabbacbdbadbcabdaadcb" becomes "adcb" (keeping the last of each unique character). 因此,像"cabbacbdbadbcabdaadcb"这样的输入变为"adcb" (保留每个唯一字符的最后一个)。 Then, with a string containing unique characters, that string's length is the answer. 然后,使用包含唯一字符的字符串,该字符串的长度就是答案。

If, for some reason, you needed the unique-character string and you needed it in the original order, you would have to reverse the original string before stripping away duplicate characters (and then reverse it again when you're done). 如果由于某种原因,您需要唯一字符串并且您需要原始顺序,则必须在删除重复字符之前反转原始字符串(然后在完成后再将其反转)。 This would require either a third-party library, StringBuffer , or a loop. 这将需要第三方库, StringBuffer或循环。

This is what I came up with: 这就是我想出的:

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;
}

I just check the index for every character, and if it's different from the original index, there are multiple occurrences. 我只检查每个字符的索引,如果它与原始索引不同,则会出现多次。

You could make a new String , called uniqueChars and initialize it to "" . 您可以创建一个名为uniqueChars的新String ,并将其初始化为"" Iterate over the characters in the String you're checking. 迭代你正在检查的String的字符。 If uniqueChars.contains(charToCheck) is false , then append that character to uniqueChars . 如果uniqueChars.contains(charToCheck)false ,则将该字符附加到uniqueChars At the end of the loop, uniqueChars.length() will tell you how many unique characters you had. 在循环结束时, uniqueChars.length()将告诉您有多少个唯一字符。 It's ugly and inefficient but it should work. 这是丑陋和低效但它应该工作。

use an ArrayList and add a charactar if not in there already: 使用ArrayList并添加一个charactar(如果不存在):

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();

Here is the program for how to write a file, how to read the same file, and how count number of times the particular character repeated: 以下是如何编写文件,如何读取同一文件以及重复特定字符的计数次数的程序:

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());
        }
    }
}

Use a vector. 使用矢量。

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

Then for every letter found, increment the position in the vector. 然后对于找到的每个字母,增加向量中的位置。 If any entries have a counter greater than 1 then you have repeats 如果任何条目的计数器大于1,那么您将重复

How about put it into an array, sort it alphabetically, then apply your logic(comparing adjacents)? 怎么样把它放入一个数组,按字母顺序排序,然后应用你的逻辑(比较邻接)?

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++;
    }
}

By the way, your program doesn't work because you do i == lengthText-1 in your for loop. 顺便说一下,你的程序不起作用,因为你在你的for循环中做了i == lengthText-1

Same logic with @Alexandre Santos, but with working sample codes. 与@Alexandre Santos相同的逻辑,但使用工作示例代码。 Complexity is O(N). 复杂性是O(N)。 Works only with alphabetical string without space, numeric or special characters. 仅适用于不带空格,数字或特殊字符的字母字符串。

This also can be used as 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]));
    }
}
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);
        }
    }
}
      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());
 }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM