【问题标题】:How to find the index of the max value from the array ,smaller or equal to the input如何从数组中找到最大值的索引,小于或等于输入
【发布时间】:2020-11-19 09:37:28
【问题描述】:

问题有点像,找到路径中的最大可达点。假设我们有一个包含 6 个元素的数组。假设数组已排序。数组的第一个元素的值为零。 考虑到数组的元素是{'0','200','375','550','750','950'}。
假设我们必须输入一个介于 0 和 950 之间的值。我们必须从数组中返回小于或等于输入值的最大值的索引。
我正在尝试使用while循环来完成这项工作,但我被卡住了!!! 这是我的代码

  void  compute_min_refills(int value, int n, vector<int>  stops) {
     int currentrefill=0,num=0,lastrefill=0;
 lastrefill = currentrefill;
    while(currentposition <= n && stops[currentposition + 1] - stops[lastposition] < Value){ 
        currentposition = currentposition + 1;
    }
    cout<<currentposition<<' ';

}

请帮助解决这个问题。

【问题讨论】:

  • 你遇到了什么问题?
  • 你还能指定什么是 n 吗?您也在比较等于 n,currentposition &lt;= n,如果 n 是数组的长度,那么我们不与 n 比较,因为最后一个元素是 n-1
  • 可以说,如果我的值是 400,那么输出应该是 2,因为 375 小于 400...但我得到 5
  • n 是数组中的元素个数
  • 你能把你的完整代码贴在这里吗?

标签: c++ arrays while-loop


【解决方案1】:

假设你的代码中nstops数组的大小,那么你可以尝试将while循环中的条件改为(currentposition &lt; n &amp;&amp; stops[currentposition] &lt;= Value)

【讨论】:

    【解决方案2】:

    试试这个:

    int index = 0;
    int newElement = 400
    while (index < n && newElement >= stops[index])
    {
        index++;
    }
    cout<<index-1;
    

    【讨论】:

    • 我认为您必须将值与行中的停止 [index] 而非当前位置进行比较 currentposition &gt;= stops[index]。如果我错了,请纠正我
    • 是的,我很困惑他对当前职位的含义,因为他的问题不清楚。我认为我编辑的答案会起作用。你怎么看?
    【解决方案3】:

    您只需将当前数组值与您要查找的值进行比较。

    currentposition = 0;
    while (currentposition <= n && stops[currentposition] < value)
    {
        ++currentposition;
    }
    cout << currentposition << ' ';
    

    【讨论】:

      【解决方案4】:

      你只需要遍历数组,直到遇到更大的值。因此,每当您遇到比输入值更大的元素时,这意味着前一个元素(在数组中)是最大的小于或等于输入值的元素。

      #include <iostream>
      
      int main() {
      
          int arr[] = {0, 200, 375, 550, 750, 950}, i = 0, val = 400, n = 6;
      
          while (i < n and arr[i] <= val) {
              i += 1;
          }
      
          (i >= 1) ? (std::cout << i - 1) : (std::cout << "No element");
      
      }
      
      

      【讨论】:

      • 只提供代码并不能解决问题。也应该包含一个好的描述。
      【解决方案5】:

      你需要做的是二分查找。它是对数组进行排序时最优化的解决方案。你可以阅读它here

      我在下面提供解决方案(代码):

      void compute_min_refills(int value, vector<int> stops) {
        // here, s denotes the start of stops
        // and, e denotes the end index of stops
        int s = 0, e = stops.size() - 1;
        // x would contain the index we're searching for
        // by default it is -1
        // if it does not change, it means
        // no such number exists which is less than or equal to value
        int x = -1;
        
        // as long as start is less than or equal end
        while(s <= e) {
          // finding middle index
          int m = (s+e) / 2;
          // check if m index satisfies the condition
          if(stops[m] <= value) {
            x = m;
            // if satisfies, then go forward
            // to check if another greater number
            // is there that satisfies the condition
            s = m + 1;
          } else {
            // if not satisfies, then go backwards
            e = m - 1;
          }
        }
        return x;
      }
      
      // now, you can just call compute_min_refills as follows
      int x = compute_min_refills(value, stops);
      // check if no such number exists
      if(x == -1) {
        printf("no such number exists\n");
      } else {
        // and print to see the result
        printf("%d\n", stops[x]);
      }
      

      【讨论】:

        【解决方案6】:

        std::find_if 算法与反向迭代器一起使用

        int input = 400;
        int arr[] = { 0, 200, 375, 550, 750, 950 };
        auto it = std::find_if(std::rbegin(arr), std::rend(arr), [&input](const int Value) { return Value <= input; });
        if (it != std::rend(arr)) {
            std::cout << "Value=" << *it << " with index=" << std::distance(it, std::rend(arr)) - 1 << std::endl;
        }
        else {
            std::cout << "Value not found" << std::endl;
        }
        
        Output:        
        Value=375 with index=2
        

        或反向循环

        int input = 400;
        int arr[] = { 0, 200, 375, 550, 750, 950 };
        for (auto beg = std::rbegin(arr); beg != std::rend(arr); ++beg)
            if (*beg <= input) {
                std::cout << "Value=" << *beg << " with index=" << (std::rend(arr) - beg - 1) << std::endl;
                break;
            }
            
        Output:        
        Value=375 with index=2
        

        或者二分查找在大数据上可能更快

        int input = 400;
        int arr[] = { 0, 200, 375, 550, 750, 950 };
        auto beg = std::begin(arr);
        auto end = std::end(arr);
        auto mid = std::begin(arr) + (end - beg) / 2;
        while (mid != end && *mid != input) {
            if (input < *mid) {
                end = mid;
            }
            else {
                if (mid + 1 == end || *(mid + 1) > input) {
                    break;
                }
                beg = mid + 1;
            }
            mid = beg + (end - beg) / 2;
        }
        if (mid != end) {
            std::cout << "Value=" << *mid << " with index=" << std::distance(std::begin(arr), mid) << std::endl;
        }
        else {
            std::cout << "Value not found" << std::endl;
        }
        
        Output:        
        Value=375 with index=2
        

        【讨论】:

          【解决方案7】:

          这是我对您尝试的方法的理解,您希望到达您可以到达的位置,一旦您的value 结束,您想要打印索引直到您到达的位置。

          这里给出的所有解决方案都正确,易于阅读且效率更高。在这里,我想建议您可以在代码和算法中修复的一些问题:

          1. 你不应该循环到&lt;=n,而是循环到n-2,因为你正在检查stops[currentposition + 1]的下一个位置。数组的最后一个索引是n-1,您不应访问大于该索引的元素。
          2. 您已经创建了一个变量lastposition,但您没有在循环中更新它。此外,我们不需要lastposition 变量,因为它将是currentPosition-1
          3. 我不确定,但您想检查一下您是否能够转到下一个位置。同样,您正在比较stops[currentposition + 1] - stops[lastposition] &lt; Value。在这里,您要做的是,在剩余的给定燃料量的情况下,我将能够走得更远。但是您没有在循环中更新value

          在您修复了代码中的一些内容后,我附上了代码 sn-p:

          #include <iostream>
          #include <vector>
          
          using namespace std;
          
          int compute_min_refills(int value, int n, vector<int>  stops){
              int currentposition = 0;
              while(currentposition < (n-1) && stops[currentposition + 1] - stops[currentposition] <= value){ 
                  int fuelSpent = stops[currentposition + 1] - stops[currentposition];
                  value = value - fuelSpent;
                  currentposition = currentposition + 1;
              }
              return currentposition;
          }
          
          int main() {
              int  i = 0, val = 1000, n = 6;
              vector<int> vect{0, 200, 375, 550, 750, 950}; 
              cout<<compute_min_refills(val,6,vect);
          }
          

          【讨论】:

            【解决方案8】:

            截至目前 7 个答案。但我真的很惊讶没有人为此提供标准功能。对于此类搜索,有一个专门为此目的设计的专用功能:std::upper_bound

            请阅读here

            这个函数将返回一个迭代器。如果你想知道索引,那么简单使用std::distance。而且由于我们想要的不是更大,而是更小或相等的值,我们将另外使用std::prev

            然后,一切都归结为一个非常简单的单行。

            请参阅下面的示例代码和一些测试向量:

            #include <iostream>
            #include <algorithm>
            #include <vector>
            #include <iterator>
            
            int main() {
                
                std::vector testValues{0,100,199,200,201,400,949,950,10000};
                
                std::vector data{0, 200, 375, 550, 750, 950};
                
                for (const int t : testValues) {
                    
                    std::cout << t << '\t' << std::distance(data.begin(),std::prev(std::upper_bound(data.begin(), data.end(), t)))<< "\n";
                }
                return 0;
            }
            

            结果将是:

            0       0                                                                                                                                                                   
            100     0                                                                                                                                                                   
            199     0                                                                                                                                                                   
            200     1                                                                                                                                                                   
            201     1                                                                                                                                                                   
            400     2                                                                                                                                                                   
            949     4                                                                                                                                                                   
            950     5                                                                                                                                                                   
            10000   5 
            

            【讨论】:

              猜你喜欢
              • 2016-09-30
              • 2021-06-09
              • 2022-01-19
              • 2021-10-24
              • 2019-08-21
              • 2018-08-09
              • 2014-12-20
              • 1970-01-01
              • 2021-03-30
              相关资源
              最近更新 更多