Find min value in array [closed]

2019-05-29 10:28发布

问题:

I have two arrays:

int playerSums[9] = { };
string playerNames[9] = { };

I am trying to get the smallest value in the array playerSums and also the array index of this value.

Here's what I've tried so far:

if (playerNames[index] == "End" || playerNames[index] == "end") {
    int lowestValue = playerSums[0];
    for (i = 1; i < sizeof(playerSums) / sizeof(playerSums[0]); i++) {
        if (playerSums[i] < lowestValue || lowestValue != 0)
            lowestValue = playerSums[i]; 
    }
    cout << index[playerNames] << " had the lowest values and got the sum ";
    cout << lowestValue << endl;
}

How do I find and display the smallest value in the array playerSums if for example only 3 players are playing, i.e. only 3 elements of the array are populated (and the rest of the elements are equal to zero)?

I need the index to display the name of the player who got the smallest value.

回答1:

You can use standard algorithm std::min_element declared in header <algorithm> that to find the element witn minimum sum. For example

#include <algorithm>

int *min = std::min_element( playerSums, playerSums + 3 );

std::cout <<  playerNames[min - playerSums] 
          << " had the lowest values and got the sum " << *min
          << std::endl;

The same can be written using standard functions std::begin, std::end and std::distance declared in header <iterator>

#include <algorithm>
#include <iterator>

int *min = std::min_element( std::begin( playerSums ), std::end( playerSums ) );

std::cout <<  playerNames[ std::distance( playerSums, min )] 
          << " had the lowest values and got the sum " << *min
          << std::endl;

Instead of using the algorithm you could write your own function similar to the algorithm. For example

size_t min_sum( int playerSums[], size_t n )
{
   size_t min = 0;

   for ( size_t i = 1; i < n; i++ )
   {
      if ( playerSums[min] < playerSums[i] ) min = i;
   }

   return min;
}

size_t min = min_sum( playerSums, sizeof( playerSums ) / sizeof( *playerSums )  );

std::cout <<  playerNames[min] 
          << " had the lowest values and got the sum " << playerSums[min]
          << std::endl;

If you need to skip elements of the array that equal to zero then the function will look like

size_t min_sum( int playerSums[], size_t n )
{
   size_t min = 0;

   while ( min < n && playerSums[i] == 0 ) ++min;

   for ( size_t i = min; i < n; i++ )
   {
      if ( playerSums[min] < playerSums[i] ) min = i;
   }

   return min;
}

size_t min = min_sum( playerSums, sizeof( playerSums ) / sizeof( *playerSums )  );

if ( min != sizeof( playerSums ) / sizeof( *playerSums ) )
{   
    std::cout <<  playerNames[min] 
              << " had the lowest values and got the sum " << playerSums[min]
              << std::endl;
}


回答2:

The same way that you are storing the lowest value in lowestValue, store the index in a variable, let's say, lowestValueIndex. Also, remove the outer if and move it inside the for loop:

if(playerNames[i] == "End" || playerNames[i] == "end")
    break;

this way, you will make sure that only the players who are playing will be processed. Also, you won't need to check if the lowest value is zero anymore. So the code will look like:

int lowestValue = playerSums[0];
int lowestValueIndex = 0;
for (int i = 1; i < sizeof(playerSums)/sizeof(playerSums[0]); ++i)
{
    if(playerNames[i] == "End" || playerNames[i] == "end")
        break;
    if (playerSums[i] < lowestValue)
    {
            lowestValue = playerSums[i];
            lowestValueIndex = i;
    }
}
cout << index[playerNames] << " had the lowest values and got the sum "
     << lowestValue << endl;

Just as a note, use an standard array that can grow to simplify this (like a vector):

std::vector<std::string> playerNames;
std::vector<int> playerSums;

for (int i = 1; i < playerSums.size(); ++i)
{
    if (playerSums[i] < lowestValue)
    {
            lowestValue = playerSums[i];
            lowestValueIndex = i;
    }
}
cout << index[playerNames] << " had the lowest values and got the sum "
     << lowestValue << endl;


回答3:

As usual the simplest solution is to use the standard library, e.g.

auto it = std::min_element(std::begin(playerSums), std::end(playerSums));
std::size_t index = std::distance(std::begin(playerSums), it);

Now you can get the min value by dereferencing the iterator it:

int lowestValue = *it;

If you only want to iterate over the first 3 elements in the array then you can do something like this instead:

auto first = std::begin(playerSums);
auto it = std::min_element(first, std::next(first, 3));
std::size_t index = std::distance(first, it);

Note: prefer std::next instead of plain pointer arithmetics (e.g. playerSums + 3) as it is more generic (works on all iterator types).



回答4:

You know the index of the element you assign to lowestValue when you change that variable's value, so just save that index in a variable (say, index), so that when you are done index has the index of the last value assigned.



回答5:

First adjust your for loop condition. I'm not sure if you defined i before so maybe you forgot that. Second the stop condition i < sizeof(palyerSums) is sufficient. Also you only need to store the index of the lowest playerSums in the array. The if condition also has something too much. If the lowestValue is not zero you will always change that value, that doesn't seem right unless the lowestValue is exactly zero.

int lowestValue = playerSums[0];
int resultIndex = 0;
for(int i = 1; i < sizeof(playerSums) / sizeof(playerSums[0]); i++) {
  if(playerSums[i] < lowestValue) {
    lowestValue = playerSums[i];
    resultIndex = i;
  }
}
cout << playerNames[resultIndex] << "blabla" << lowestValue; // instead of lowestValue you could also do playerSums[resultIndex] ofcourse.

Let me know if that works



标签: c++ arrays min