Java 我的程序的时间复杂度是多少?
我一直在分析解决类问题的运行时复杂性 我有一个代表服务器的大数组,数组的每个元素代表一条终端线。终端线路包含许多用户及其计数。我的工作是读取一个文件,该文件每行包含一个数字和字符字符串,将它们存储在数组中,并找到每一终端行上计数最高的用户 但是,我很难确定解决方案(LineReport类)的时间复杂性。Java 我的程序的时间复杂度是多少?,java,algorithm,performance,time-complexity,big-o,Java,Algorithm,Performance,Time Complexity,Big O,我一直在分析解决类问题的运行时复杂性 我有一个代表服务器的大数组,数组的每个元素代表一条终端线。终端线路包含许多用户及其计数。我的工作是读取一个文件,该文件每行包含一个数字和字符字符串,将它们存储在数组中,并找到每一终端行上计数最高的用户 但是,我很难确定解决方案(LineReport类)的时间复杂性。 针对N个输入行和O(N)个不同的用户,分析LineReport的大O CPU性能,从而在部分完成后分析每个列表上的O(N)个条目 public class LineReport { pr
针对N个输入行和O(N)个不同的用户,分析LineReport的大O CPU性能,从而在部分完成后分析每个列表上的O(N)个条目代码>
public class LineReport {
private LineUsage[] lines = new LineUsage[501];
private String lineInfo = "";
private int lineNum = 0;
/**
* reads a file once per line via command line, splits each line of string
* into two parts, line number and username, and feeds the username into
* an array of LineUsage object with line number as the index of array.
*/
public void readMessages() {
Scanner scan = new Scanner(System.in);
while(scan.hasNextLine()) {
lineInfo = scan.nextLine();
String[] temp = new String[2];
temp = lineInfo.split(" ");
lineNum = Integer.parseInt(temp[0]);
if (lines[lineNum] != null) {
lines[lineNum].addObservation(temp[1]);
} else {
lines[lineNum] = new LineUsage();
lines[lineNum].addObservation(temp[1]);
}
}
scan.close();
}
/**
* writes the most common user of each terminal line with its count
* to console in following format:<br>
* Line# Username Count<br>
* 1   joe     100
*/
public void showReport() {
System.out.println("Line Most Common User Count:\n");
for (int i = 1; i < lines.length; i++) {
if (lines[i] != null) {
Usage maxUsage = lines[i].findMaxUsage();
System.out.println((i) + " " + maxUsage.getUsername() + " " + maxUsage.getCount());
} else {
System.out.println((i) + " NONE 0");
}
}
}
}
公共类LineReport{
专用线路用法[]线路=新线路用法[501];
私有字符串lineInfo=“”;
私有int lineNum=0;
/**
*通过命令行每行读取一次文件,拆分每行字符串
*分为两部分,行号和用户名,并将用户名输入到
*LineUsage对象的数组,行号作为数组的索引。
*/
公共无效读消息(){
扫描仪扫描=新扫描仪(System.in);
while(scan.hasNextLine()){
lineInfo=scan.nextLine();
字符串[]临时=新字符串[2];
temp=lineInfo.split(“”);
lineNum=Integer.parseInt(temp[0]);
如果(行[lineNum]!=null){
行[lineNum].addObservation(temp[1]);
}否则{
lines[lineNum]=新的LineUsage();
行[lineNum].addObservation(temp[1]);
}
}
scan.close();
}
/**
*写入每个终端行的最常见用户及其计数
*以以下格式进行控制台:
*行#用户名计数
*1&emsp;&emsp;乔&emsp;&emsp;&emsp;&emsp;100
*/
公开报告({
System.out.println(“行最常见用户计数:\n”);
对于(int i=1;i
公共类行用法{
私人地图用户;
LineUsage(){
this.users=new HashMap();
}
/**
*在映射中插入给定的用户名字符串
*/
public void addObservation(字符串用户名){
如果(username.length()>40){
抛出新的IllegalArgumentException(“用户名不得超过40个字符”);
}
if(users.containsKey(用户名)){
users.put(用户名,users.get(用户名)+1);
}否则{
users.put(用户名,1);
}
}
/**
*遍历映射并找到计数和返回数最高的用户
*已找到用户及其计数的Usage对象实例
*@返回找到用户的即时使用对象及其计数
*/
公共用法findMaxUsage(){
字符串maxUser=“”;
int maxCount=0;
for(字符串用户名:users.keySet()){
if(users.get(username)>maxCount){
maxUser=用户名;
maxCount=users.get(用户名);
}
}
返回新用法(maxUser、maxCount);
}
}
在我看来,这是一个O(n^2)解。它有两种方法readMessages()
和showReport()
readMessages()
有一个while循环和一个O(n)方法split()
*所以这就是n*n=n^2
showReport()
还有一个循环和一个O(n)方法addObservation()
这是另一个n*n=n^2
。因此,整个类是n^2+n^2=2n^2
。去掉常数,我的复杂度为O(n^2)
如果我有什么错误,请纠正我。
提前谢谢
*类的时间复杂度是而不是O(n^2)
。方法showReport()
和readMessages()
的时间复杂度都是O(n)
split(String regex)
的时间复杂度为O(n)
,其中n是输入字符串中的字符数。在您的例子中,N
不是那样,N
是输入字符串的数量;每个这样的字符串由行号和用户名组成。在split()
因此,split()
方法的复杂性是而不是O(n)。它将是O(k)
,其中k是输入字符串中的字符数(而不是n
,因为n
已经代表了您案例中的其他内容)。因此,readMessages()
方法的总体复杂性是O(n*k)
但是,如果字符数不超过某个限制,例如100(在您的情况下,这是正确的,因为用户名不能超过40个字符,行号几乎不包含k个数字),那么拆分函数的复杂度将是O(100),这将减少到O(1)。为了简化,如果k不会超过某个特定常数,无论输入是什么n
,那么复杂性将降低到O(n)
方法showReport()
的时间复杂度为O(n)。在showReport()
方法中,有一个for循环
,它将运行n次
。在for循环的迭代中,有一个对方法findMaxUsage()
的调用,只要hashMap中有一个条目,该方法就会运行
为了使showReport()
方法的复杂性为O(n^2),num
public class LineUsage {
private Map<String, Integer> users;
LineUsage() {
this.users = new HashMap<String, Integer>();
}
/**
* inserts given string of username into map
*/
public void addObservation(String username) {
if (username.length() > 40) {
throw new IllegalArgumentException("username must be no more than 40 characters");
}
if (users.containsKey(username)) {
users.put(username, users.get(username) + 1);
} else {
users.put(username, 1);
}
}
/**
* iterates through map and find the user with highest count and returns
* an instance of Usage object with found user and its count
* @return the instant of Usage object with found user and its count
*/
public Usage findMaxUsage() {
String maxUser = "";
int maxCount = 0;
for (String username: users.keySet()) {
if (users.get(username) > maxCount) {
maxUser = username;
maxCount = users.get(username);
}
}
return new Usage(maxUser, maxCount);
}
}