字符串中的数字频率

时间:2015-12-27 19:53:25

标签: java string

我应该这样做:

  

对于每个数字的输入数字打印频率,按其出现的顺序排列。例如:
  输入:56464
  输出:
  数频
  5 -1
  6 -2
  4 -2

我不能使用除java.lang和Scanner之外的任何其他库来输入
所以我尝试了这个:

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

我哪里出错了请帮帮忙。

4 个答案:

答案 0 :(得分: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()));
    }
}

答案 1 :(得分:1)

sb.replace(sb.charAt(x),'*');

几乎没有问题
  1. replace会替换所有字符,而不仅仅是第一个字符,这就是为什么c不能大于1的原因。
  2. 字符串是不可变的,因此replace无法编辑原始字符串,它会返回带有替换字符的新字符,您可以将其存储在sb引用中。
  3. 无论如何,如果你能够使用java.lang.*java.util.Scanner旁边的其他Java资源,那么简单的方法就是使用Map来映射字符及其出现次数。非常有用的是,Java 8中添加的merge方法允许我们传递key initialValue combination 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));
    

答案 2 :(得分: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 :(得分:0)

问题是,如上所述,String是不可变的,因此String.replace()只返回一个新字符串,而不会(不能)修改原始字符串。您应该使用StringBuilder,或存储返回的值(例如sb = sb.replace(sb.charAt(x),'*');)。

更进一步,因为您使用c初始化0,如果没有其他相关字符出现(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
    }
}