Tails递归方法计算标准差

时间:2011-09-30 18:26:45

标签: java

public class StampaInversa {

private static class NumberWithCounterAndAverage{
    private int number=0;
    private int counter=1;
    private int average=0;
    public int getNumber(){
        return number;
    }
    public int getCounter(){
        return counter;
    }
    public void setNumber(int number){
            this.number=number;
    }
    public void setCounter(int counter){
        this.counter+=counter;
    }

    public int getAverage(){
        return avrage;
    }
    public void setAverage(int average){
        this.average=average;
    }

    public String toString(){
        return "Number: "+number+"Counter "+counter+"Average "+average;
    }//toString
}//NumeroConContatore

public static void reversePrint(){
    Scanner sc= new Scanner(System.in);
    System.out.println("Insert number");
    int x=sc.nextInt();
    if(x==0) return;
    reverseprint();
    System.out.println(x);
}

public static int sumPrint(){
    Scanner sc=new Scanner(System.in);
    System.out.println("Insert number");
    int x=sc.nextInt();
    if(x!=0) x+=sumPrint();
    return x;
}

public static NumberWithCounterAndAverage printAverage(){
    Scanner sc=new Scanner(System.in);
    NumberWithCounterAndAverage ncc= new NumberWithCounterAndAverage();
    System.out.println("Insert number");
    int x=sc.nextInt();
    if(x!=0){
        NumberWithCounterAndAverage nccem= printAverage();
        ncc.setNumber(x+nccem.getNumber());
        ncc.setCounter(+nccem.getCounter());
    }
    if (x!=0){
        ncc.setAverage(ncc.getNumber()/(ncc.getCounter()-1));
    }
    return ncc;
}

public static void main(String[] args) {
    NumberWithCounterAndAverage nccem= printAverage();
    System.out.println(nccem.getCounter()+" "+nccem.getNumber()+" average "+nccem.getAverage());
}
}//StampaInversa

我的教授。给了我一个作业:写尾递归函数来计算:
插入从输入到0插入的数字的总和;
插入直到0的数字的平均值;
插入数字的标准偏差直到0;

完成作业的条件是:
不允许任何数据结构(数组,arraryslist,LinkedList ...),只允许使用ad hoc对象(例如我创建的对象:NumberWithCounterAndAverage)
不允许使用任何变量,变量必须仅由函数拥有 该函数必须是递归的。

上面代码中的函数完美地工作,但现在我需要做一个递归函数来计算上面描述的条件的标准偏差。你有什么线索吗?

如果还不清楚该功能应该如何,请告诉我。

3 个答案:

答案 0 :(得分:1)

我认为你应该考虑的想法是有一个函数,它将计算所需的当前计数,总和,平均值等作为参数。这将支持您对无实例变量的要求,与上述内容不同。

对此方法的第一次调用将传递全部为零。每个后续调用将读入一个值,如果不是0,则使用更新的值调用自身。如果为零,则进行最终计算并输出结果。

答案在这篇文章中:How to efficiently calculate a running standard deviation?

通过这个计算:让方法取 sum_x,sum_x2和count。 (sum_x是元素的总和,sum_x2是平方的总和)。在收到0的迭代中,结果为:

sum = sum_x
average = sum_x / count
stdev = sqrt((sum_x2 / count) - (average * average)) 

答案 1 :(得分:1)

要计算标准差,您必须为输入的每个金额平方该金额与平均值之间的差值。在输入所有元素之前,您无法知道平均值。因此,您必须在从函数返回时计算标准偏差。

要计算标准偏差,您需要计数,平均值和累加器的平方差之和。这将是您的“NumberWithCounterAndAverage”类。

在构建堆栈的初始调用期间,我会在每次递归时输入一个数字,并将count和sum变量作为参数传递。

答案 2 :(得分:0)

我已经解决了这项任务,感谢大家。这是解决方案, 我已将双标准偏差添加到上面代码中的对象

 public static NumberWithCounterAndAverage calculateStandardDeviation(){
    Scanner sc= new Scanner(System.in);
    NumberWithCounterAndAverage nccem= new NumberWithCounterAndAverage();
    System.out.println("Insert number");
    int x= sc.nextInt();
    int counter=1;
    int sum=x;
    nccem=calculateStandardDeviation(sum, counter);

    int partialDeviationSum=((x-nccem.getAverage())*(x-nccem.getAverage()));
    nccem.setDeviazioneStandard(partialDeviationSum+nccem.getStandardDeviation());

    double standardDeviation= Math.sqrt(nccem.getStandardDeviation());
    nccem.setStandardDeviation(standardDeviation);

    return nccem;
}
public static NumberWithCounterAndAverage calculateStandardDeviation(int sum, int counter){
    Scanner sc= new Scanner(System.in);
    NumberWithCounterAndAverage nccem= new NumberWithCounterAndAverage();
    System.out.println("Insert number");
    int x= sc.nextInt();
    int partialSum=0, partialCounter=0;
    if(x!=0){
        partialSum= x+sum;
        partialCounter=1+counter;
        nccem=calculateStandardDeviation(partialSum, partialCounter);
    }
    if(x==0){//I am at the top of the stack, I calculate the average and i go down
        nccem.setAverage(sum/counter);
    }
    if(x!=0){
        int sumPartialDeviation=((x-nccem.getAverage())*(x-nccem.getAverage()));
        nccem.setStandardDeviation(sumPartialDeviation+nccem.getStandardDeviation());
    }

    return nccem;
}