算法學習【2】字符個數統計

      牛客網的華爲機試題庫有一道題:字符個數統計。


      若直接用兩個for循環則會發生錯誤,錯誤的程序如下:

import java.util.Scanner;
public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextLine()){
			String str = sc.nextLine();
			int n = 0;
			for(int i=0;i<str.length()-1;i++){
				for(int j=i+1;j<str.length();j++){
					if(str.charAt(i) == str.charAt(j)){
						n++;
					}
				}
			}
			System.out.println("重複字符個數:"+n);
			System.out.println("不同字符統計:"+(str.length()-n));
		}
	}
}

輸出結果:

aasd
重複字符個數:1
不同字符統計:3
asd
重複字符個數:0
不同字符統計:3
aaasd
重複字符個數:3
不同字符統計:2
aaaasd
重複字符個數:6
不同字符統計:0

      最近冒泡法寫習慣了,就導致了這樣的錯誤,錯誤根源在當有三個以上的字符出現時,計算結果爲組合C(n, m) = n!/m!/(n-m)!,出現重複情況。

      因此,建立一個輸入字符串長度的數組,用於統計每個字符的個數, 同時將數組中重複字符對應位置的值設置爲-1,結果如下:

import java.util.Scanner;
public class MyCode6 {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		sc.close();
		int len = str.length();
		
		int[] count = new int[len];
		for(int i=0;i<len;i++){
			for(int j=0;j<len;j++){			
				if(str.charAt(i)==str.charAt(j)){
					if(i>j){
						count[i]=-1;//重複元素
						break;
					}else{
						count[i]++;
					}
				}
			}
		}
		
		int sum = 0;
		for(int k=0;k<len;k++){
			if(count[k]>0)
				sum++;
		}
		System.out.println(sum);
		
	}
}
      以上程序經驗證正確。


     而題目並未要求統計各個字符的個數,因此可以用boolean類型的數組表示,節約空間。

import java.util.Scanner;
public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		sc.close();
		int len = str.length();
		boolean[] count = new boolean[len];
		
		for(int i=0;i<len;i++){
			for(int j=0;j<len;j++){			
				if(str.charAt(i)==str.charAt(j)){
					if(i>j){
						
					}else if(i<j){
						count[i] = true;//重複元素
					}
				}
			}
		}
		
		int sum = 0;
		for(int k=0;k<len;k++){
			if(count[k]==false)
				sum++;
		}
		System.out.println(sum);
		
	}
}
      以上程序經驗證正確。


      但當輸入的字符串過長時,建立的數組也就越長,有可能超過允許長度。由題可知,輸入字符的ASCii碼值都在0~127範圍內,因此可以建立一個長度爲128的boolean數組,判斷每個字符是否存在。

import java.util.Scanner;

public class MyCode5 {
public static void main(String args[]) {
	
	Scanner sc = new Scanner(System.in);
	String str = sc.nextLine();
	sc.close();
	boolean [] arr=new boolean[128];
	
        for(int i=0;i<str.length();i++){
            int t=(int)str.charAt(i);
            if(t>127){
                continue;
            }
            arr[t]=true;
        }
        
        int sum=0;
        for(int i=0;i<arr.length;i++){
            if(arr[i]){
            	sum++;
            }
        }
        
        System.out.println(sum);
	}
}

      以上程序經驗證正確。

   

      除此之外,我們還可以使用集合框架來簡化程序。

     例如HashSet類,它實現了set接口,而set接口不允許存在重複的元素。

import java.util.*;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		sc.close();
		
		HashSet<Character> hs = new HashSet<Character>();
		for(int i=0;i<str.length();i++){
			hs.add(str.charAt(i));
		}
		
		System.out.println(hs.size());
	}
}
      以上程序經驗證正確。

      例如映射類HashMap 類,它實現了Map接口,映射(Map)要求鍵唯一,也可以實現去重的效果。




發佈了43 篇原創文章 · 獲贊 50 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章