2015-12-27 81 views
1

我應該做到這一點:位頻率在一個字符串

對於其occurrence.For例如的順序中的每個號碼的輸入號碼的打印頻率:
輸入:56464
輸出:
編號頻
5 -1
6 -2
4 -2

我無法使用除了java.lang和掃描任何其他庫輸入
所以,我想這一點:

package practice2; 

import java.util.Scanner; 

public class DigitFrequency2 
{ 

    private static Scanner sc; 

    public static void main(String[] args) 
    { 
     sc = new Scanner(System.in); 
     System.out.println("Enter an integer number"); 
     String sb = sc.nextLine(); 
     System.out.println("Number\tFrequency"); 

     int i,x,c = 0; 

     for(i=0;i<sb.length();i++) 
     { 
      c = 0; 
      for(x = i+1;x<sb.length();x++) 
      { 
       if(sb.charAt(i) == sb.charAt(x) && sb.charAt(i) != '*' && sb.charAt(x) != '*') 
       { 
        c++; 
        sb.replace(sb.charAt(x),'*'); 
       } 
      } 

      if(c>0) 
      { 
       System.out.println(sb.charAt(i)+"  \t"+c); 
      } 

     } 
    } 
} 

Number Frequency 
6  1 
4  1 

我要去哪裏錯了,請幫忙。

+3

好,'sb.replace()'不會做你的代碼什麼:字符串是不可改變的。可能你打算將字符串分配給StringBuilder? – markspace

+0

我不能使用StringBuilder :( –

+0

我與StringBuilder的做在這裏http://pastebin.com/vvDsvHYm –

回答

0

問題是,如前所述,String是不變的,所以String.replace()剛剛返回新的字符串,它不(不能)修改原來的。您應該使用StringBuilder,或者存儲返回的值(例如sb = sb.replace(sb.charAt(x),'*');)。

的進一步深入,因爲你初始化c0,它會留0如果有問題(sb.charAt(i))的字符沒有其他發生,使你的算法不會檢測並只出現一次打印數字(因爲後來你只打印如果c > 0)。

計算字符串中字符或數字的出現次數(頻率)是一項簡單的操作,它不需要創建新字符串,只需循環一次即可完成。

這是一個更高效的解決方案(最快的一個)。由於數字在'0'..'9'範圍內,因此您可以創建一個數組,在該數組中可以計算出現次數,並且只能循環一次字符。無需替換任何東西。發生順序在另一個order char數組中被「記住」。

char[] order = new char[10]; 
int[] counts = new int[10]; 
for (int i = 0, j = 0; i < sb.length(); i++) 
    if (counts[sb.charAt(i) - '0']++ == 0) 
     order[j++] = sb.charAt(i); // First occurrence of the digit 

並打印在順序,直到order陣列被填充:

System.out.println("Number\tFrequency"); 
for (int i = 0; order[i] != 0; i++) 
    System.out.println(order[i] + "\t" + counts[order[i] - '0']); 

輸出示例:

Enter an integer number 
56464 
Number Frequency 
5  1 
6  2 
4  2 

爲了完整性,這裏的完整main()方法:

public static void main(String[] args) { 
    System.out.println("Enter an integer number"); 
    String sb = new Scanner(System.in).nextLine(); 

    char[] order = new char[10]; 
    int[] counts = new int[10]; 
    for (int i = 0, j = 0; i < sb.length(); i++) 
     if (counts[sb.charAt(i) - '0']++ == 0) 
      order[j++] = sb.charAt(i); // First occurrence of the digit 

    System.out.println("Number\tFrequency"); 
    for (int i = 0; order[i] != 0; i++) 
     System.out.println(order[i] + "\t" + counts[order[i] - '0']); 
} 

注:

如果你想使你的代碼對無效輸入安全(可能含有非數字),你可以使用Character.isDigit()。這裏僅僅是for循環是對任何輸入安全:

for (int i = 0, j = 0; i < sb.length(); i++) { 
    char ch = sb.charAt(i); 
    if (Character.isDigit(ch)) { 
     if (counts[ch - '0']++ == 0) 
      order[j++] = ch; // First occurrence of ch 
    } 
} 
+0

它必須按發生的順序 –

+0

@RayyanMerchant對不起,我錯過了你的問題。請參閱已編輯的答案,現在按發生順序進行跟蹤和打印 – icza

+0

任何downvoters可以評論爲什麼downvotes? – icza

0

這應該是一個很好的代碼使用用戶輸入的打印頻率:

public static void main(String args[]) 
    { 
     System.out.println("Please enter numbers "); 
     String time = in.nextLine(); //USER INPUT 
     time = time.replace(":", ""); 
     char digit[] = {time.charAt(0), time.charAt(1), time.charAt(2), time.charAt(3)}; 
     int[] count = new int[digit.length]; 
     Arrays.sort(digit); 

     for (int i = 0; i < digit.length; i++) 
     { 
      count[i]++; 
      if (i + 1 < digit.length) 
      { 
       if (digit[i] == digit[i + 1]) 
       { 
        count[i]++; 
        i++; 
       } 
      } 
     } 

     for (int i = 0; i < digit.length; i++) 
     { 
      if (count[i] > 0) 
      { 
       System.out.println(digit[i] + " appears " + count[i]+" time(s)"); 
      } 
     } 
    } 
3

簡單的方法是這樣的。不會打擾評論,因爲很清楚發生了什麼事情。

Scanner in = new Scanner(System.in); 
while (true) { 
    System.out.print("Input String: "); 
    String line = in.nextLine(); 

    while (!line.isEmpty()) { 
     char c = line.charAt(0); 
     int length = line.length(); 
     line = line.replace(String.valueOf(c), ""); 
     System.out.println(c + " " + (length - line.length())); 
    } 
} 
+0

簡潔和足智多謀的解決方案。這不會按頻率對輸出進行排序 – schwobaseggl

+0

@schwobaseggl是的,他並不希望它的頻率。「它的發生順序」儘管這將適用於所有事情,但他總是可以根據自己的需求進行改進,例如「只有整數「和whatnot –

+0

Lolz現在我明白爲什麼沒有人打擾......你是絕對正確的!'發生'顯然不是'發生次數'的同一事物+1從我 – schwobaseggl

1

很少有問題sb.replace(sb.charAt(x),'*');

  1. replace替換所有字符,這不僅是第一個爲什麼你c不能擦菜板大於1
  2. 字符串是不可變的如此以來, replace無法編輯原始字符串,它將返回新的替換字符,您可以將其存回sb參考。

無論如何,如果你將能夠使用其他Java資源旁邊java.lang.*java.util.Scanner簡單的方法是使用Map將字符映射其發生次數。非常有幫助這裏是merge方法的Java 8中添加允許我們傳遞keyinitialValuecombination of old and new value

所以,你的代碼可以是這樣的:

String sb = ... 

Map<Character, Integer> map = new TreeMap<>(); 
for (char ch : sb.toCharArray()) { 
    map.merge(ch, 1, Integer::sum); 
} 
map.forEach((k, v) -> System.out.println(k + "\t" + v)); 
+0

」不能使用任何其他庫除了java.lang和Scanner輸入「地圖將是我的第一個選項,雖然。 –

+0

@JohnE。謝謝。我試圖分開兩個部分使最後o更像是與OP不同的其他讀者可以使用的獎金。 – Pshemo