The program below takes inputs for the temperature in various cities in a span of multiple days. It then outputs the ones where the minimal temperature is closer to the average than the maximal temperature, prefaced by the number of cities where this happens.
For example: "3 5 10 15 12 10 10
11 11 11 11 20
12 16 16 16 20"
returns "2 1 2".
I've ran it with various particularly large inputs a few times, and the program seems to slow down with larger numbers. Is there any way to make the program faster?
class Program
{
static void Main(string[] args)
{
string input = Console.ReadLine();
string[] inputs = input.Split();
int cities = Convert.ToInt32(inputs[0]);
int days = Convert.ToInt32(inputs[1]);
int[] content = new int[days];
int i = 0;
int y = 0;
float max = 0;
float average = 0;
float min = 50;
int how_many = 0;
List<int> which = new List<int>();
for (i = 0; i < cities; i++)
{
input = Console.ReadLine();
inputs = input.Split();
for (y = 0; y < days; y++)
{
content[y] = Convert.ToInt32(inputs[y]);
average += content[y];
if (content[y] > max)
{
max = content[y];
}
if (content[y] < min)
{
min = content[y];
}
}
average = (float)average / days;
if (max - average > average - min)
{
how_many += 1;
int position = i + 1;
which.Add(position);
}
max = 0;
average = 0;
min = 50;
y = 0;
}
Console.Write(how_many + " ");
i = 0;
for (i = 0; i < which.Count(); ++i)
{
Console.Write(which[i] + " ");
}
Console.ReadKey();
}
}
-
\$\begingroup\$ How big is a "particularly large inputs"? 100 cities? 1,000 cities? 300 days? I fixed some small memory issues in your code testing it but it runs pretty quick. \$\endgroup\$CharlesNRice– CharlesNRice2019年12月30日 21:06:18 +00:00Commented Dec 30, 2019 at 21:06
-
\$\begingroup\$ 1,000 cities, 1,000 days. Could you send me the code if possible? \$\endgroup\$Pizza64210– Pizza642102019年12月30日 21:14:16 +00:00Commented Dec 30, 2019 at 21:14
1 Answer 1
If you want to see how performance is you need to get the user input out of the loop. I'm assuming you don't want to measure the time it takes someone to type in or paste in the data elements.
You don't need the variable how_many
as it will always be the same as the Count
of which
, which by the way isn't a good name for a variable even something like results would be better name.
You also don't need the context
array variable. Just need to store the current value not save each element as it loops through.
The variables i, y, max, average, min
can all be declared in the loop scope and not need to be reset.
Calling Count()
on which.Count()
is the Linq Count method, should just call the list Count property
I'm also assuming this is a beginner question and won't get into Console as input and validating the data coming from it is valid.
I personally didn't want to type in all the data so I made the computer generate random data, if in debug mode
static void Main(string[] args)
{
#if DEBUG
var random = new Random();
var inputs = "1000 1000".Split();
#else
var inputs = Console.ReadLine().Split();
#endif
var cities = Convert.ToInt32(inputs[0]);
var days = Convert.ToInt32(inputs[1]);
var data = new List<int[]>(cities);
for (var i = 0; i < cities; i++)
{
#if DEBUG
var cityData = Enumerable.Range(0, days)
.Select(_ => random.Next(100))
.ToArray();
#else
var cityData = Console.ReadLine()
.Split()
.Select(x => Convert.ToInt32(x))
.ToArray();
#endif
if (cityData.Length != days)
{
Array.Resize(ref cityData, days);
}
data.Add(cityData);
}
var timer = new Stopwatch();
timer.Start();
var results = new List<int>();
for (var i = 0; i < cities; i++)
{
float max = float.MinValue;
float average = 0;
float min = float.MaxValue;
for (var y = 0; y < days; y++)
{
var content = data[i][y];
average += content;
if (content > max)
{
max = content;
}
if (content < min)
{
min = content;
}
}
average = average / days;
if (max - average > average - min)
{
int position = i + 1;
results.Add(position);
}
}
Console.Write(results.Count + " ");
Console.WriteLine(string.Join(" ", results));
timer.Stop();
Console.WriteLine();
Console.WriteLine($"Total Processing Time: {timer.Elapsed}");
Console.ReadKey();
}
This code runs in less than a second on my machine. I assume waiting for user input was what was taking the longest time in pervious one and not actually the processing of the data.
-
1\$\begingroup\$ Thank you very much for the answer! This will help me a lot in learning programming. \$\endgroup\$Pizza64210– Pizza642102019年12月30日 21:40:27 +00:00Commented Dec 30, 2019 at 21:40
-
\$\begingroup\$ @Pizza64210 FYI I fixed bug in the code. Needed Split() after the "1000 1000" \$\endgroup\$CharlesNRice– CharlesNRice2019年12月30日 22:14:34 +00:00Commented Dec 30, 2019 at 22:14