Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的程序的时间复杂度是多少?_Java_Algorithm_Performance_Time Complexity_Big O - Fatal编程技术网

Java 我的程序的时间复杂度是多少?

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

我一直在分析解决类问题的运行时复杂性

我有一个代表服务器的大数组,数组的每个元素代表一条终端线。终端线路包含许多用户及其计数。我的工作是读取一个文件,该文件每行包含一个数字和字符字符串,将它们存储在数组中,并找到每一终端行上计数最高的用户

但是,我很难确定解决方案(LineReport类)的时间复杂性。
针对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 &emsp;&emsp;joe &emsp;&emsp;&emsp; 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);
    }
}