如何解决数组数字计数和分割问题?

3

我将尝试使用C#来进行一些问题解决练习,同时也是对C#新手。下面是问题:给定数组arr=[1,1,0,-1,-1],它有5个元素,两个正数,两个负数和一个零。它们的比率分别为2/5=0.400000(两个正数字),2/5=0.400000(两个负数字)和1/5=0.200000(一个零)。应该按以下方式打印:

0.400000
0.400000
0.200000

我实际上想做的是,统计一个数组中所有负数的数量,并将其除以数组中所有元素的总数。对于数组中的正数和零也是同样的情况。最后,它会打印出3个结果。这是我尝试过的代码,但输出不是我想要的结果。
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System;

class Solution {

    // Complete the plusMinus function below.
    static void plusMinus(int[] arr) {
        int[] positiveArray = new int[arr.Length];
        int[] negativeArray = new int[arr.Length];
        int[] zeroArray = new int[arr.Length];

        for(int i=0; i <arr.Length; i++){
            if(arr[i]>0){

                arr[i]=positiveArray[i];

            }else if(arr[i]<0){
                arr[i] = negativeArray[i];
            }else if(arr[i] == 0){
                arr[i] = zeroArray[i];
            }
        }
        float postive = (float)positiveArray.Length/arr.Length;
        float negative = (float)negativeArray.Length/arr.Length;
        float zero = (float)zeroArray.Length/arr.Length;

        Console.WriteLine(postive);
        Console.WriteLine(negative);
        Console.WriteLine(zero);

    }

    static void Main(string[] args) {
        int n = Convert.ToInt32(Console.ReadLine());

        int[] arr = Array.ConvertAll(Console.ReadLine().Split(' '), arrTemp => Convert.ToInt32(arrTemp))
        ;
        plusMinus(arr);
    }
}

输出示例:

在此输入图像描述


(注:本文中的html标签已保留)

1
请问您能否添加一个带有输入和输出的示例? - Franco Fusaro
当然。谢谢你提醒我添加输出示例。 - Mohsin
4个回答

2

由于这是C#,你可以使用一些花哨的LINQ。

Console.WriteLine((float)arr.Count(n => n  > 0)/(float)arr.Length);
Console.WriteLine((float)arr.Count(n => n  < 0)/(float)arr.Length);
Console.WriteLine((float)arr.Count(n => n == 0)/(float)arr.Length);

1

这里有几个问题。让我看看能否帮助您决定如何处理它们。

您的任务是颠倒的。

在您想将元素分类到相应数组的部分,您正在错误地分配项目。而不是这样:

for(int i=0; i <arr.Length; i++){
    if(arr[i]>0){
        arr[i]=positiveArray[i];
    }else if(arr[i]<0){
        arr[i] = negativeArray[i];
    }else if(arr[i] == 0){
        arr[i] = zeroArray[i];
    }
}

试试这个:

for(int i=0; i <arr.Length; i++){
    if(arr[i]>0){
        positiveArray[i] = arr[i];
    }else if(arr[i]<0){
        negativeArray[i] = arr[i];
    }else if(arr[i] == 0){
        zeroArray[i] = arr[i];
    }
}

现在,我认为我理解了你的算法思路,但现在我们有一个更大的问题。
这3个数组的大小始终相同,并且等于原始数组中的总项目数。
这就是问题所在。在开始计数循环之前,您创建了数组,根据它们的类别(正数、负数、零)保存项目,但问题是在C#中,我们必须预先保留要使用的数组的大小,因此您总是将原始数组的长度分配给每个创建的数组。因此,所有数组的大小都相同,因此您始终会得到1作为结果。
可能的解决方案:
提示1:对于这种类型的问题,您不需要实际存储数组值,而只需对它们进行计数即可。因此,解决此问题的一种可能方法是创建计数器而不是数组,每次增加适当的计数器,然后使用这些计数器来计算最终结果。
现在你已经使用了列表解决了这个问题,我会给你一些建议。即使你已经解决了问题,你也应该考虑你是否高效地解决了它,以及如何改进它。(提示:在这种情况下,使用列表会浪费很多空间) 我建议你阅读更多关于运行时/空间算法分析的资料。这将教你如何编写更好的代码。有很多资料可供选择。这是我通过快速谷歌搜索找到的一个链接:https://www.cs.cmu.edu/~adamchik/15-121/lectures/Algorithmic%20Complexity/complexity.html 如果你想尝试不使用列表的可能解决方案,我会留下这个fiddle给你。

https://dotnetfiddle.net/01R09n

希望这能帮到你!

1
非常感谢您指出我的错误。使用List这次成功了。 - Mohsin
不客气!对于这个问题使用列表并不是最好的解决方案。我强烈建议您使用计数器来解决。我会更新答案以提供更多细节。 - Karel Tamayo

0

好的,现在通过这个例子我可以猜测你的问题是你已经在以下代码行中指定了数组的长度:

    int[] positiveArray = new int[arr.Length];
    int[] negativeArray = new int[arr.Length];
    int[] zeroArray = new int[arr.Length];

所以当你进行除法运算时,由于所有数组的长度都与原始数组相同,因此你总是得到1。一种解决方案是删除数组长度的初始化,但如果这样做,当在正数、负数和零数组中插入时,你将遇到另一个问题,并且必须通过改变插入方式来修复它。

我建议你像这篇帖子推荐的那样,将数组更改为List<T>

干杯!


非常感谢您。列表是解决方案。 - Mohsin

0
你得到每个计算结果都为 1 的原因是你在除以相同的数字。而 new int[arr.Length] 的长度与 arr.Length 是相同的。
但是,你可以统计不同数字的出现次数,比如:
var positiveCount = 0;
// with the negative numbers and zeros also

for(int i=0; i <arr.Length; i++){
    if(arr[i]>0){
        positiveCount++;
    }
    // and so on...
}

//then divide with the length:
var positive = (float)positiveCount/arr.Length;

那对我来说真的很简短,也省了很多时间。谢谢您先生。 - Mohsin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接