我应该这样做:
对于每个数字的输入数字打印频率,按其出现的顺序排列。例如:
输入: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
我哪里出错了请帮帮忙。
答案 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),'*');
:
replace
会替换所有字符,而不仅仅是第一个字符,这就是为什么c
不能大于1的原因。replace
无法编辑原始字符串,它会返回带有替换字符的新字符,您可以将其存储在sb
引用中。无论如何,如果你能够使用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
}
}