函数返回最大值的索引,跳过以前返回的值

时间:2016-04-11 17:26:34

标签: c++

我需要在c ++中创建一个返回最大值索引的函数。每当调用它时,它应该跳过它先前返回的索引并返回存储下一个最大值的索引。

例如: -

int a [8] = {2,6,4,12,5,7,12,8}

该函数应该返回3然后是6然后是7,5,1,4,2,0

编辑: -

#include <iostream>
#include <vector>

using std::vector;

int return_max_index(vector<int> valuebyweight, int n)
{
    int max_index = 0;

    for(int i=0; i<n; i++)
     {
      if(valuebyweight[i] >= valuebyweight[max_index])
       {
        max_index = i;
       }
     }

 return max_index;

}

double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
  double value = 0.0;

  vector<int> valuebyweight(n);

  for(int i=0; i<n; i++)
  {

      valuebyweight[i] = values[i] / weights[i];
  }


while(capacity!=0)

 {
    int max_index = return_max_index(valuebyweight, n);

    if(weights[max_index] <= capacity)
    {
        capacity -= weights[max_index];
        value += values[max_index];
    }

    else
    {
        value += (valuebyweight[max_index] * capacity);
        capacity = 0;
    }
 }
  return value;
}

int main() {
  int n;
  int capacity;
  std::cin >> n >> capacity;
  vector<int> values(n);
  vector<int> weights(n);
  for (int i = 0; i < n; i++) {
    std::cin >> values[i] >> weights[i];
  }

  double optimal_value = get_optimal_value(capacity, weights, values,n);

  std::cout.precision(10);
  std::cout << optimal_value << std::endl;
  return 0;
}

尝试实现分数背包算法。如果我在输入上运行代码

3 50
60 20
100 50
120 30

它应该给出答案180,但它返回200,因为我的&#39; return_max_index&#39;函数再次返回相同的索引(2)但我想以某种方式希望它跳过它之前返回的索引(2)并返回具有下一个最高值的权重的索引。即0.

4 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是将已找到的索引列表保留在静态本地。但是,你怎么知道你以前还没见过这个呢?所以最好把它变成一个类。然后你也可以做一些优化:对数组进行一次排序,然后只要它被调用就从结果中弹出下一个最高的索引:

struct mysort{
    const std::vector<int>& _tosort;
    mysort(const std::vector<int> tosort) : _tosort(tosort) {}
    bool operator()(int a, int b){ return _tosort[a] < _tosort[b]; }
}


class IndexFinder{
private:
    std::vector<int> sorted_indices;
    int invoked;
public:
    IndexFinder(const std::vector<int>& tosort) :
      sorted_indices(tosort.size()) {
        invoked = 0;
        for(size_t i=0; i<tosort.size(); ++i)
            sorted_indices[i] = i;
        std::stable_sort(sorted_indices.begin(), sorted_indices.end(),
                          mysort(tosort));
    }

    int IndexFinder::operator()(){
        return sorted_indices[invoked++];
    }
}; 

你应该对IndexFinder :: operator()()进行保护,以处理如果用户调用它的次数多于向量中的索引。作为奖励,您应该可以非常轻松地将其更改为模板类,以对除int之外的内容进行排序。

答案 1 :(得分:1)

试试这个代码。我做了一些小改动。

#include <iostream>
#include <vector>

using std::vector;

int return_max_index(vector<int> valuebyweight, int n)
{
    int max_index = 0;

    for(int i=0; i<n; i++)
     {
      if(valuebyweight[i] >= valuebyweight[max_index])
       {
        max_index = i;
       }
     }
     //if all the values in valuebyweight are 0
     if(valuebyweight[max_index]==0)
     {
      return -1;
     }
     else
     return max_index;

}

double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
  double value = 0.0;

  vector<int> valuebyweight(n);

  for(int i=0; i<n; i++)
  {

      valuebyweight[i] = values[i] / weights[i];
  }


while(capacity!=0)

 {
    int max_index = return_max_index(valuebyweight, n);
    if(max_index==-1)
    {
     break;
    }
    if(weights[max_index] <= capacity)
    {
        capacity -= weights[max_index];
        value += values[max_index];
        // assign valuebyweight[max_index] to 0 as it already participated in optimal solution and need no longer to participate. 
        valuebyweight[max_index]=0;
    }

    else
    {
        value += (valuebyweight[max_index] * capacity);
        capacity = 0;
    }
 }
  return value;
}

int main() {
  int n;
  int capacity;
  std::cin >> n >> capacity;
  vector<int> values(n);
  vector<int> weights(n);
  for (int i = 0; i < n; i++) {
    std::cin >> values[i] >> weights[i];
  }

  double optimal_value = get_optimal_value(capacity, weights, values,n);

  std::cout.precision(10);
  std::cout << optimal_value << std::endl;
  return 0;
}

答案 2 :(得分:0)

这不是很好(它修改了数组),但提出了一个想法:

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

int index_of_largest(int array[], size_t len) {
  int r = INT_MIN;
  int d = 0;
  for (int i = 0; i < len; i++) {
    if (array[i] > r) {
      d = i;
      r = array[i];
    }
  }
  if (r != INT_MIN) {
    array[d] = INT_MIN;
  }
  return d;
}

int main(){
  int a[8] = {2, 6, 4, 12, 5, 7, 12, 8};
  int len = (int)(sizeof(a) / sizeof(a[0]));
  for (int i = 0; i < len; i++) {
    printf("%d\n", index_of_largest(a, len));
  }
}

<强>输出

3
6
7
5
1
4
2
0

答案 3 :(得分:0)

这与上一个@bloer给出的答案略有不同,但是通过使用C ++ 11(std::iotastd::sort中的lambda用法显示了一些更短的方法(它仍然使用了一个类) )。

#include <algorithm>
#include <iostream>
#include <vector>

class MaxIndex
{
    private:
        std::vector<int> index;

    public:
        MaxIndex(const std::vector<int>& tosort) : index(tosort.size()) 
        {
           // initialize the indices
           std::iota(index.begin(), index.end(), 0);

           // sort the indices based on passed-in vector
           std::sort(index.begin(), index.end(), [&](int n1, int n2)
                     { return tosort[n1] > tosort[n2];});
        }

        // return the nth highest index 
        int getNthMaxIndex(int n) const { return index[n]; }
};

using namespace std;

int main()
{
   std::vector<int> a = {2,6,4,12,5,7,12,8};
   MaxIndex mi(a);
   for (size_t i = 0; i < a.size(); ++i)
      cout << mi.getNthMaxIndex(i) << endl;
}

Live Example

其次,如果您要使用n,是否有理由持续使用std::vectorstd::vector知道自己的大小,因此传递(和使用)表示向量中元素数量的无关变量会引发某个地方引入的错误。如果你想获得元素的数量,或者只是自己传递矢量,只需使用std::vector::size()函数。

此外,您应该通过引用或const引用传递std::vector之类的内容,具体取决于是否更改了传入的向量。按值传递std::vector(正如您现在所做的那样)会产生(不必要的)副本。