Ето ти един начин за решение на задача 3, ако ти е труден за разбиране кажи ми и ще ти пратя друг, който е чрез процедурно програмиране и е по-лесен за смилане и разбиране.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class CategorizeNumbersAndFindMinMaxAverage
{
static void Main()
{
double[] numbers = Array.ConvertAll(Console.ReadLine().Split(' '), s => double.Parse(s));
var floatNumbers = numbers.Where(i => i != (int)i);
var roundN = numbers.Where(i => i == (int)i);
if (floatNumbers.Count()>0)
{
Console.WriteLine("[{0}] -> min: {1}, max: {2}, sum: {3}, avg: {4:f2}",string.Join(" ",floatNumbers),floatNumbers.Min(),floatNumbers.Max(),floatNumbers.Sum(),floatNumbers.Average());
}
if (roundN.Count() > 0)
{
Console.WriteLine();
Console.WriteLine("[{0}] -> min: {1}, max: {2}, sum: {3}, avg: {4:f2}", string.Join(" ", roundN), roundN.Min(), roundN.Max(), roundN.Sum(), roundN.Average());
}
}
}
Ето още една идея за разделянето на float и int числа:
foreach (float num in inputList)
{
if (num % 1 < Double.Epsilon)
{
IntList.Add(i);
}
else
{
FloatList.Add(i);
}
}
v list ili v array go zadavash?
inputList е лист, но ще стане и с array.
@Gabbs:
И аз започнах със същата идея, но Double.Epsilon e константа, представляваща "the smallest positive Double value that is greater than zero". Което означава, че не намирах правилно дали е цяло число, или не.
Промених си метода за проверка по следния начин:
public static bool isAlmostRound(double num)
{
double epsilon = Math.Max(Math.Abs(num), Math.Abs(num)) * 1E-15;
return Math.Abs((num - Math.Floor(num))) <= epsilon;
}
Избрах си достатъчно малко число, за да е (относително) прецизно сравнението.. и за да работи.
А цялото ми решение може да погледнете тук.
Ето и от мен :)
using System;
using System.Linq;
using System.Collections.Generic;
class MinMaxAvg
{
static void Main()
{
//Write a program that reads N floating-point numbers from the console. Your task is to separate them in two sets,
//one containing only the round numbers (e.g. 1, 1.00, etc.) and the other containing the floating-point numbers with non-zero
//fraction. Print both arrays along with their minimum, maximum, sum and average (rounded to two decimal places).
string input = Console.ReadLine();
double[] numb = input.Split(' ').Select(double.Parse).ToArray();
List<double> intList = new List<double>();
List<double> doubleList = new List<double>();
int doubleCount = 0;
int intCount = 0;
for (int i = 0; i < numb.Length; i++)
{
if (numb[i] % 1 != 0)
{
doubleList.Add(numb[i]);
}
else
{
intList.Add(numb[i]);
}
}
Console.WriteLine("[{0}] -> min: {1}, max: {2}, sum: {3}, avg: {4:F2}"
,string.Join(", ",doubleList), doubleList.Min(), doubleList.Max(), doubleList.Sum(), doubleList.Average());
Console.WriteLine("[{0}] -> min: {1}, max: {2}, sum: {3}, avg: {4:F2}"
, string.Join(", ", intList), intList.Min(), intList.Max(), intList.Sum(), intList.Average());
}
}
Пускам си и моето решение:
Ето едно решение и от мен. :) http://pastebin.com/XWnZ5k8E
Здравейте,
за тази задача се опитвам да намеря решение от 2 дни и все не ми се струват достатъчно прецизни.
Ако се ползва double при директен опит за сравняване като:
if (numb[i] % 1 != 0), се подчертават от ReSharper-a, че може да доведе до грешка.
За Double.Epsilon в MSDN пише, че не се препоръчва да се ползва, когато се сравнява дали две числа са равни.
Накрая стигнах до ето такова решение, но не съм убедена дали е най-оптималното.
Ако някой по-напреднал следи темата, може ли да сподели?
Ако в реална работна обстановка ни се случи да решаваме подобна задача, как трябва да постъпим?
Благодаря!
Не смятам, че съм от "по-напредналите", но коментирах малко по-нагоре относно Double.Epsilon. Отне ми известно време ровене в stackoverflow, преди да си формулирам как точно да напиша проверката, за да работи добре. Не знам дали е най-оптималното решение, но се надявам да ти е от полза.
Това, което пише в страницата на майкрософт, е за общия случай на сравняване на две double числа - в такъв случай разликата между тях може да е доста голяма.
В нашия случай, знаем, че разликата между двете числа ще е < 1 (реално ще представлява числата след запетаята), и използването на absolute error става за този специфичен случай.
Ако решим да сравняваме много различни double числа (примерно 3.5 и 8483843.7 , а не 3.5 и 3.0), ще използваме relative error (както l.s.bozhinov го е направил по-нагоре).
По принцип, наистина е по-добра идея да се използва relative error, но за тази специфична задача Double.Epsilon върши работа.
Ето го и моето решение:
static void Main()
{
var input = Console.ReadLine().Split();
double [] numbers = input.Select(p => Convert.ToDouble(p)).ToArray();
List <double> rounded = new List <double> ();
List <double> nonRounded =new List <double> ();
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] == Math.Round(numbers[i]))
rounded.Add(numbers[i]);
else
nonRounded.Add(numbers[i]);
}
Console.WriteLine("[{0}] -> min: {1:f2}, max: {2:f2}, sum: {3:f2}, avg: {4:f2}", string.Join(", ", nonRounded), nonRounded.Min(), nonRounded.Max(), nonRounded.Sum(), nonRounded.Average());
Console.WriteLine("[{0}] -> min: {1:f2}, max: {2:f2}, sum: {3:f2}, avg: {4:f2}", string.Join(", ", rounded), rounded.Min(), rounded.Max(), rounded.Sum(), rounded.Average());
}