ฉันจะรับค่าสูงสุด (หรือต่ำสุด) ในเวกเตอร์ได้อย่างไร


123

ฉันจะรับค่าสูงสุด (หรือต่ำสุด) ในเวกเตอร์ในC ++ ได้อย่างไร

ฉันได้เห็นวิธีแก้ปัญหาบางอย่างสำหรับสิ่งนี้ใน Google แต่ไม่มีวิธีใดที่เหมาะสมสำหรับฉัน :(

ใครช่วยอธิบายวิธีการหาค่าสูงสุดหรือต่ำสุดจากเวกเตอร์ให้เข้าใจง่าย ๆ หน่อยได้ไหม และฉันคิดผิดที่คิดว่าอาร์เรย์จะเหมือนกันมากหรือน้อย?

ฉันต้องการตัววนซ้ำใช่ไหม ฉันลองแล้วmax_elementแต่ยังคงได้รับข้อผิดพลาด?

vector<int>::const_iterator it;
it = max_element(cloud.begin(), cloud.end());

ข้อผิดพลาด: ขอสมาชิก 'เริ่มต้น' ใน 'คลาวด์' ซึ่งเป็นประเภทที่ไม่ใช่คลาส 'int [10]'

แก้ไข:ยังตอบไม่ได้ ??? ฉันจะวางไว้ที่นี่ ...

ว้าวขอบคุณสำหรับการตอบกลับที่รวดเร็ว! ฉันลงเอยด้วยวิธีนี้คิดว่ามันโอเคไหม?

for (unsigned int i = 0; i < cdf.size(); i++)
  if (cdf[i] < cdfMin)
    cdfMin = cdf[i];

ที่cdfเป็นเวกเตอร์


ดูเหมือนcloudไม่ใช่คอนเทนเนอร์ STL แต่เป็นint[10]ไฟล์. โดยทั่วไปไม่ได้เป็นสมาชิกcloud .begin()อาจต้องการรับหนังสือ C ++ พื้นฐานเว้นแต่คุณจะทำสิ่งนี้เพียงสิ่งเดียว
Chris A.

โค้ดเพิ่มเติมบางอย่างอาจมีประโยชน์เช่นกัน คำจำกัดความของคลาวด์อยู่ที่ไหน?
ทิม

9
@bobblob: แต่ข้อผิดพลาดของคอมไพเลอร์ที่คุณโพสต์บอกว่า "คลาวด์เป็นประเภทที่ไม่ใช่คลาสint[10]" แล้วมันจะเป็นเวกเตอร์ได้อย่างไร?
jalf

คำตอบ:


118

คุณสามารถใช้แฟล็กคอมไพล์ c ++ 11 / c ++ 0x ได้

auto it = max_element(std::begin(cloud), std::end(cloud)); // c++11

มิฉะนั้นเขียนของคุณเอง:

template <typename T, size_t N> const T* mybegin(const T (&a)[N]) { return a; }    
template <typename T, size_t N> const T* myend  (const T (&a)[N]) { return a+N; }

ดูสดได้ที่http://ideone.com/aDkhW :

#include <iostream>
#include <algorithm>

template <typename T, size_t N> const T* mybegin(const T (&a)[N]) { return a; }    
template <typename T, size_t N> const T* myend  (const T (&a)[N]) { return a+N; }

int main()
{
    const int cloud[] = { 1,2,3,4,-7,999,5,6 };

    std::cout << *std::max_element(mybegin(cloud), myend(cloud)) << '\n';
    std::cout << *std::min_element(mybegin(cloud), myend(cloud)) << '\n';
}

โอ้และใช้std::minmax_element(...)ถ้าคุณต้องการทั้งสองอย่างพร้อมกัน: /


สวัสดีคุณรู้หรือไม่ว่าสามารถนำไปใช้กับอาร์เรย์มิติหรือเวกเตอร์ได้?
Charles Chow

3
ใช่คุณสามารถ. อัลกอริธึมไลบรารีมาตรฐานได้รับการออกแบบมาเพื่อทำงานกับตัววนซ้ำ พอยน์เตอร์เป็นตัวทำซ้ำด้วย
sehe

85

หากคุณต้องการใช้ฟังก์ชันstd::max_element()วิธีที่คุณต้องทำคือ:

double max = *max_element(vector.begin(), vector.end());
cout<<"Max value: "<<max<<endl;

ฉันหวังว่านี่จะช่วยได้


10
เหตุผลที่มี*ใน*max_element?
Konrad

39
นั่นเป็นเพราะ´max_element´ คืนค่าตัววนซ้ำ
Angie Quijano

ฉันเดาว่าคุณได้สมมติว่าอินพุตเป็นเวกเตอร์ <double> หรือไม่ * max_element () โดยค่าเริ่มต้น return double val
Sameer Kape

14

ปล่อย,

 #include <vector>

 vector<int> v {1, 2, 3, -1, -2, -3};

หากเวกเตอร์เรียงลำดับจากน้อยไปมากหรือมากไปหาน้อยคุณจะพบว่ามีความซับซ้อน O (1)

สำหรับเวกเตอร์จากน้อยไปหามากองค์ประกอบแรกเป็นองค์ประกอบที่เล็กที่สุดคุณสามารถหาได้โดย v [0] (0 ตามดัชนี) และองค์ประกอบสุดท้ายเป็นองค์ประกอบที่ใหญ่ที่สุดคุณสามารถหาได้โดย v [sizeOfVector-1]

หากเวกเตอร์เรียงลำดับจากมากไปหาน้อยองค์ประกอบสุดท้ายเป็นองค์ประกอบที่เล็กที่สุดคุณจะได้รับโดย v [sizeOfVector-1] และองค์ประกอบแรกเป็นองค์ประกอบที่ใหญ่ที่สุดคุณจะได้รับโดย v [0]

หากไม่ได้จัดเรียงเวกเตอร์คุณจะต้องวนซ้ำบนเวกเตอร์เพื่อให้ได้องค์ประกอบที่เล็กที่สุด / ใหญ่ที่สุดในกรณีนี้ความซับซ้อนของเวลาคือ O (n) ที่นี่ n คือขนาดของเวกเตอร์

int smallest_element = v[0]; //let, first element is the smallest one
int largest_element = v[0]; //also let, first element is the biggest one
for(int i = 1; i < v.size(); i++)  //start iterating from the second element
{
    if(v[i] < smallest_element)
    {
       smallest_element = v[i];
    }
    if(v[i] > largest_element)
    {
       largest_element = v[i];
    }
}

คุณสามารถใช้ iterator

for (vector<int>:: iterator it = v.begin(); it != v.end(); it++)
{
    if(*it < smallest_element) //used *it (with asterisk), because it's an iterator
    {
      smallest_element = *it;
    }
    if(*it > largest_element)
    {
      largest_element = *it;
    }
}

คุณสามารถคำนวณได้ในส่วนอินพุต (เมื่อคุณต้องหาองค์ประกอบที่เล็กที่สุดหรือใหญ่ที่สุดจากเวกเตอร์ที่กำหนด)

int smallest_element, largest_element, value;
vector <int> v;
int n;//n is the number of elements to enter
cin >> n;
for(int i = 0;i<n;i++)
{
    cin>>value;
    if(i==0)
    {
        smallest_element= value; //smallest_element=v[0];
        largest_element= value; //also, largest_element = v[0]
    }

    if(value<smallest_element and i>0)
    {
        smallest_element = value;
    }

    if(value>largest_element and i>0)
    {
        largest_element = value;
    }
    v.push_back(value);
}

นอกจากนี้คุณยังสามารถรับองค์ประกอบที่เล็กที่สุด / ใหญ่ที่สุดได้ด้วยฟังก์ชันในตัว

#include<algorithm>

int smallest_element = *min_element(v.begin(),v.end());

int largest_element  = *max_element(v.begin(),v.end());

คุณสามารถรับองค์ประกอบที่เล็กที่สุด / ใหญ่ที่สุดของช่วงใดก็ได้โดยใช้ฟังก์ชันนี้ เช่น,

vector<int> v {1,2,3,-1,-2,-3};

cout << *min_element(v.begin(), v.begin() + 3); //this will print 1,smallest element of first three elements

cout << *max_element(v.begin(), v.begin() + 3); //largest element of first three elements

cout << *min_element(v.begin() + 2, v.begin() + 5); // -2, smallest element between third and fifth element (inclusive)

cout << *max_element(v.begin() + 2, v.begin()+5); //largest element between third and first element (inclusive)

ฉันใช้เครื่องหมายดอกจัน (*) ก่อนฟังก์ชัน min_element () / max_element () เพราะทั้งคู่ส่งคืน iterator รหัสทั้งหมดอยู่ใน c ++


2
min_elementและmax_elementส่งคืนตัวทำซ้ำไม่ใช่ตัวชี้ อย่างไรก็ตามเพื่อให้ถูกต้องในทางเทคนิคตัวชี้เป็นส่วนย่อยของตัววนซ้ำ ดู: stackoverflow.com/questions/2728190/…
rayryeng

ฉันได้อัปเดตคำตอบของฉันแล้ว ขอบคุณสำหรับการสังเกตของคุณ
Taohidul Islam

9

สมมติว่าคลาวด์int cloud[10]สามารถทำได้ดังนี้: int *p = max_element(cloud, cloud + 10);


จะลองดูด้วย ฉันพยายามก่อนหน้านี้เพื่อรับ max_element แต่ไม่มีความรัก ขอบคุณ!
bob blob

7

คุณสามารถพิมพ์ได้โดยตรงโดยใช้ฟังก์ชัน max_element / min_element เช่น:

  cout<<*max_element(v.begin(),v.end());

  cout<<*min_element(v.begin(),v.end());

5

ใน c ++ 11 คุณสามารถใช้ฟังก์ชันบางอย่างเช่นนี้:

int maxAt(std::vector<int>& vector_name) {
    int max = INT_MIN;
    for (auto val : vector_name) {
         if (max < val) max = val;
    }
    return max;
}

เนื่องจากคุณกำลังอ้างอิง C ++ 11 จึงดีกว่าใช้std::max_elementเพราะ ... ?
rayryeng

1

หากคุณต้องการใช้ตัววนซ้ำคุณสามารถสร้างตำแหน่งใหม่ด้วยอาร์เรย์

std::array<int, 10> icloud = new (cloud) std::array<int,10>;

สังเกตการขาด()ในตอนท้ายซึ่งเป็นสิ่งสำคัญ สิ่งนี้จะสร้างคลาสอาร์เรย์ที่ใช้หน่วยความจำนั้นเป็นที่เก็บข้อมูลและมีคุณลักษณะ STL เช่นตัวทำซ้ำ

(นี่คือ C ++ TR1 / C ++ 11 โดยวิธีการ)


1

คุณสามารถใช้ max_element เพื่อรับค่าสูงสุดในเวกเตอร์ max_element ส่งคืนตัววนซ้ำเป็นค่าที่ใหญ่ที่สุดในช่วงหรือสุดท้ายหากช่วงว่างเปล่า เนื่องจากตัววนซ้ำเป็นเหมือนตัวชี้ (หรือคุณสามารถพูดได้ว่าตัวชี้เป็นรูปแบบของตัววนซ้ำ) คุณสามารถใช้ * นำหน้าเพื่อรับค่าได้ ดังนั้นตามปัญหาคุณจะได้รับองค์ประกอบสูงสุดในเวกเตอร์เป็น:

int max=*max_element(cloud.begin(), cloud.end());

มันจะให้องค์ประกอบสูงสุดใน "เมฆ" เวกเตอร์ของคุณ หวังว่าจะช่วยได้


0

แค่นี้:

// assuming "cloud" is:
// int cloud[10]; 
// or any other fixed size

#define countof(x) (sizeof(x)/sizeof((x)[0]))

int* pMax = std::max_element(cloud, cloud + countof(cloud));

ทำไมต้องใช้มาโคร ไม่มีเหตุผลสำหรับสิ่งนั้น! ข้อผิดพลาดเริ่มต้นด้วยint cloud[10];และเป็นการใช้ตัวเลขวิเศษ
Ulrich Eckhardt

1
เพราะจากข้อผิดพลาดเป็นที่ชัดเจนว่าเขาไม่มีเวกเตอร์ แต่เป็นอาร์เรย์ปกติ และคุณต้องนับความยาวของมันเพื่อหลีกเลี่ยงการใช้ตัวเลขเวทย์มนตร์ที่เข้ารหัส เขาอาจเปลี่ยนความยาวในอนาคต แต่รหัสสำหรับการหาค่าสูงสุดด้วยวิธีนี้จะเหมือนกัน
ivan.ukr

ขออภัยที่ไม่ถูกต้อง วิธีแก้ปัญหาของคุณถูกต้อง แต่ไม่ดี เหตุผลก็คือสมมติว่าใช้ตัวเลขวิเศษซึ่งไม่เป็นไปตามข้อความแสดงข้อผิดพลาด จากนั้นต่อด้วยการใช้มาโครซึ่งมักจะเป็นกลิ่นรหัส
Ulrich Eckhardt

-5
#include <stdlib.h>
#include <stdio.h>

int main()
{

    int vector[500];

    vector[0] = 100;
    vector[1] = 2;
    vector[2] = 1239;
    vector[3] = 5;
    vector[4] = 10;
    vector[5] = 1;
    vector[6] = 123;
    vector[7] = 1000;
    vector[8] = 9;
    vector[9] = 123;
    vector[10] = 10;

    int i = 0;

    int winner = vector[0];

    for(i=0;i < 10; i++)
    {
        printf("vector = %d \n", vector[i]);

        if(winner > vector[i])
        {
            printf("winner was %d \n", winner);
            winner = vector[i];
            printf("but now is %d \n", winner);
        }
    }

    printf("the minimu is %d", winner);
}

วิธี nooby ที่สมบูรณ์ ... ใน C


3
สิ่งนี้ตอบคำถามเกี่ยวกับวิธีหาค่าสูงสุดในอาร์เรย์ไม่ใช่ C ++vector
Andrew Stubbs

คำถามนี้ติดแท็ก C ++ คุณได้เขียนโค้ดนี้ในภาษา C แต่ไม่เพียงแค่นั้นคุณกำลังเทียบเวกเตอร์กับอาร์เรย์ - ไม่ถูกต้อง นอกจากนี้คุณยังมีข้อความสั่งพิมพ์ที่ไม่จำเป็นเมื่อเราต้องการค่าจริง ในที่สุดรหัสทั้งหมดก็กวนใจ คุณเพียงแค่ต้องการรหัสในforลูป โดยรวมแล้วคำตอบที่แย่มาก
rayryeng
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.