csrss Ответов: 2

Найдите наиболее распространенные числа в массиве


Вопрос в том какой алгоритм мне нужен для решения этой задачи:

У меня есть множество поплавков:
10.21313
10.456
10.234324
10.45758
11.4564747
10.45647
10.32425
9.34536
9.4578689
100.345345
129.3453
1.456456
10.345
10.235363
10.23425

Мне нужно извлечь из этого массива только те элементы, которые наиболее распространены, например 10.*, 11.* и 9.* - они наиболее близки по значению друг к другу. На концептуальном уровне есть ли уже алгоритм для этого, или я должен изобрести свой собственный?

Что я уже пробовал:

Я еще ничего не пробовал.

2 Ответов

Рейтинг:
1

OriginalGriff

В какой-то степени это будет зависеть от того, что именно вы подразумеваете под "рядом": 10.4-это "рядом" 10, но 10.5-это около 10 или 11? А как насчет 10.4999? 10.50001?
Решите, что представляет собой "близость", и вы можете работать оттуда.

Тогда то, как я это сделаю, будет зависеть от языка и / или фреймворка, в котором я работаю: решение C# может быть одной строкой кода, SQL-более длинным, но использовать те же идеи. Решение javascript было бы совсем другим!

Например, в C# это просто так:

double [] data = { 10.21313, 10.456, 10.234324, 10.45758, 11.4564747, 10.45647, 10.32425, 9.34536, 9.4578689, 100.345345, 129.3453, 1.456456, 10.345, 10.235363, 10.23425 };
var common = data.GroupBy(d => GetNearest(d)).Select(g => g.Key);
Вам придется написать или заменить GetNearest метод сам, основанный на вашем решении, как указано выше.


csrss

Да, близость должна быть рассчитана на основе чисел в массиве. Таким образом, мы можем видеть, что 10 близко к 9 и близко к 11, но не близко к 100 или 1. Из того, что я знаю, есть некоторые алгоритмы кластеризации, но не уверен, что они подойдут здесь?
Язык - это C#

Maciej Los

Пожалуйста, смотрите мой ответ. Там вы найдете объяснение тому, что сказал OriginalGriff.

Рейтинг:
0

Maciej Los

В дополнение к оригинальному решению Гриффа... Пожалуйста, внимательно прочтите, что написал OriginalGriff.

Как GetNearest метод вы можете использовать один из следующих способов:
Математика.Метод Пола (Система) | Microsoft Docs[^]
Математика.Потолочный Метод (Система) | Microsoft Docs[^]
Увидеть разницу:

Value          Ceiling          Floor
7.03                8              7
7.64                8              7
0.12                1              0
-0.12                0             -1
-7.1               -7             -8
-7.6               -7             -8


Вы также можете использовать Математика.Метод Округления (Система) | Microsoft Docs[^] или явное преобразование[^] в целое число:

double [] data = { 10.21313, 10.456, 10.234324, 10.45758, 11.4564747, 10.45647, 10.32425, 9.34536, 9.4578689, 100.345345, 129.3453, 1.456456, 10.345, 10.235363, 10.23425 };

var NearestDown = data
	.GroupBy(x=> (int)x)
	.Select(grp=> new
	{
		Key = grp.Key,
		Count = grp.Count(),
		Values = string.Join(";", grp.Select(x=>x))
	})
	.OrderByDescending(x=>x.Count)
	.ToList();


Результат:
Key Count Values
10   9    10.21313;10.456;10.234324;10.45758;10.45647;10.32425;10.345;10.235363;10.23425 
9    2    9.34536;9.4578689 
11   1    11.4564747 
100  1    100.345345 
129  1    129.3453 
1    1    1.456456


csrss

Да, но я знаю, как найти наиболее распространенные числа в массиве int. Вероятно, речь идет об алгоритме кластеризации данных. Я просто хотел узнать, есть ли какие-то применимые.

Maciej Los

Что ж.. Что касается алгоритма кластеризации данных, то здесь нет набора встроенных алгоритмов. Каждый раз, когда вы хотите сгруппировать, разделить или агрегировать данные, вам нужно определить, чего вы хотите достичь; какие зависимости вы хотите найти и т. д. Я бы посоветовал прочитать о "больших данных" или "значении данных". Короче говоря: в то время как данные означают процесс, вы обычно должны использовать набор методов. Этот набор "заданий для выполнения" известен под общим названием: алгоритм. Удачи вам!