0

更新 01 感谢 Caius,找到了主要问题,“如果”的逻辑错误,现在已修复并给出正确的结果。该循环仍然会在辅助列表上创建比需要更多的位置,为主列表上的每个数字一个额外的位置。

我已经更新了下面的代码以供参考以下问题:

-001 我可以弄清楚为什么它会创建需要的位置,for 循环应该只在 foreach 正确完成其循环后运行?-002 为了解决这个问题,我使用了 List.Remove() 来删除所有的 0,到目前为止没有崩溃,但是,我正在创建额外的索引,而不是删除它们,确实意味着如果我有大量数字,性能会下降吗?或者是一个可以接受的解决方案?

描述

它应该读取中央 List1 (numberList) 中的所有数字,并计算在某个 (0|-15 / 15|-20) 范围内有多少数字,因为我使用另一个 List,每个范围都是一个位置List2 (numberSubList),其中 List2 上的每个数字都表示该范围内存在多少个数字。- 范围随着数字的增加或减少而变化

代码:

void Frequency()
        {

            int minNumb = numberList.Min();
            int maxNumb = numberList.Max();
            int size = numberList.Count();

            numberSubList.Clear();
            dGrdVFrequency.Rows.Clear();
            dGrdVFrequency.Refresh();

            double k = (1 + 3.3 * Math.Log10(size));
            double h = (maxNumb - minNumb) / k;

            lblH.Text = $"H: {Math.Round(h, 2)} / Rounded = {Math.Round(h / 5) * 5}";
            lblK.Text = $"K: {Math.Round(k, 4)}";

            if (h <= 5) { h = 5; }
            else { h = Math.Round(h / 5) * 5; }
            

            int counter = 1;
            for (int i = 0; i < size; i++)
            {
                numberSubList.Add(0); // 001 HERE, creating more positions than needed, each per number.
                foreach (int number in numberList)
                {
                    if (number >= (h * i) + minNumb && number < (h * (i + 1)) + minNumb)
                    {
                        numberSubList[i] = counter++;
                    }
                }
                numberSubList.Remove(0); // 002-This to remove all the extra 0's that are created.
                counter = 1;
            }

            txtBoxSubNum.Clear();
            foreach (int number in numberSubList)
            {
                txtBoxSubNum.AppendText($"{number.ToString()} ,  ");
            }

            lblSubTotalIndex.Text = $"Total in List: {numberSubList.Count()}";
            lblSubSumIndex.Text = $"Sum of List: {numberSubList.Sum()}";

            int inc = 0;
            int sum = 0;
            foreach (int number in numberSubList)
            {
                sum = sum + number;
                int n = dGrdVFrequency.Rows.Add();
                dGrdVFrequency.Rows[n].Cells[0].Value = $"{(h * inc) + minNumb} |- {(h * (1 + inc)) + minNumb}";
                dGrdVFrequency.Rows[n].Cells[1].Value = $"{number}";
                dGrdVFrequency.Rows[n].Cells[2].Value = $"{sum}";
                dGrdVFrequency.Rows[n].Cells[3].Value = $"{(number * 100) / size} %";
                dGrdVFrequency.Rows[n].Cells[4].Value = $"{(sum * 100) / size} %";
                inc++;
            }
        }

显示更新版本的屏幕截图。

视觉工作

4

1 回答 1

0

我认为,如果您的目标是仅将例如 17 存储在“15 到 25”插槽中,那么这很奇怪:

if (number <= (h * i) + minNumb) // Check if number is smaller than the range limit

因为它是在一个循环中找到的,该循环将移动到下一个范围“25 到 35”,并且它只询问数字 17 是否小于上限(并且 17 小于 35),因此 17 符合 25-也有35范围

FWIW 一个数字应该在的范围可以从数字中得出,(number - min) / number_of_ranges此时您创建了例如 10 个范围,然后您访问每个数字 10 次以将其放入一个范围,因此您执行的操作比你真的需要

于 2020-10-11T06:05:03.210 回答