วิธีรับตำแหน่งขององค์ประกอบบางอย่างในเวกเตอร์สตริงเพื่อใช้เป็นดัชนีในเวกเตอร์ ints


100

ฉันกำลังพยายามหาดัชนีขององค์ประกอบในเวกเตอร์ของstringsเพื่อใช้เป็นดัชนีในเวกเตอร์intประเภทอื่นเป็นไปได้หรือไม่

ตัวอย่าง:

vector <string> Names;
vector <int> Numbers;

 ... 
// condition to check whether the name exists or not
if((find(Names.begin(), Names.end(), old_name_)) != Names.end())  
    {   // if yes
        cout <<"Enter the new name."<< endl;
        cin >> name;
        replace(Names.begin(), Names.end(), old_name_, name);
    }

ตอนนี้ผมต้องการที่จะได้รับตำแหน่งของold_nameในNamesเวกเตอร์ที่จะใช้ในการเข้าถึงองค์ประกอบบางอย่างในNumbersเวกเตอร์ เพื่อที่ฉันจะได้พูดว่า:

Numbers[position] = 3 ; // or whatever value assigned here.

ฉันลองใช้:

vector <string> :: const_iterator pos;
pos = (find(Names.begin(), Names.end(), old_name_))
Numbers[pos] = 3;

แต่เห็นได้ชัดว่าสิ่งนี้ใช้ไม่ได้เนื่องจากposเป็นสตริงประเภท!


ฉันเดาว่าน่าจะstackoverflow.com/questions/1425349/…
Francesco Vollero

คุณควรตรวจสอบ std :: map หรือ std :: unordered_map
Etherealone

คำตอบ:


159

หากต้องการรับตำแหน่งขององค์ประกอบในเวกเตอร์โดยทราบว่าตัววนซ้ำที่ชี้ไปยังองค์ประกอบนั้นให้ลบออกv.begin()จากตัววนซ้ำ:

ptrdiff_t pos = find(Names.begin(), Names.end(), old_name_) - Names.begin();

ตอนนี้คุณต้องตรวจสอบposกับNames.size()เพื่อดูว่ามันจะออกจากขอบเขตหรือไม่:

if(pos >= Names.size()) {
    //old_name_ not found
}

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

เริ่มต้นด้วย C ++ 11 คุณสามารถใช้std::distanceแทนการลบสำหรับทั้งตัววนซ้ำและตัวชี้:

ptrdiff_t pos = distance(Names.begin(), find(Names.begin(), Names.end(), old_name_));

ขอโทษนะไม่เห็นความคิดเห็นของ @Bob__ อาจจะถูกลบไปแล้ว? ฉันสงสัยว่าทำไมptrdiff_tจะดีกว่าsize_tเนื่องจากptrdiff_t จะยกคำเตือนของการเปรียบเทียบระหว่างจำนวนเต็มลงนามและไม่ได้ลงนาม
Hiraku

3
@Hiraku เขาลบความคิดเห็นของเขาแล้ว เขาแนะนำให้ใช้ptrdiff_tเนื่องจากช่วยให้คุณสามารถจัดเก็บระยะห่างระหว่างคู่ของตัวทำซ้ำลงในคอนเทนเนอร์เดียวกันได้แม้ในสถานการณ์ที่ผลลัพธ์เป็นลบ หากเราใช้size_tเราต้องระวังอย่าลบตัววนซ้ำที่ใหญ่กว่าออกจากตัววนซ้ำที่เล็กกว่า
dasblinkenlight

เพื่อให้แม่นยำยิ่งขึ้นคุณควรเพิ่ม "#include <algorithm>" (สำหรับการใช้ std :: find) ผู้เขียนคำถามละเว้น "รวม" นี้ด้วย
Grag2015

92

หากคุณต้องการดัชนีคุณสามารถใช้std::findร่วมกับstd::distance.

auto it = std::find(Names.begin(), Names.end(), old_name_);
if (it == Names.end())
{
  // name not in vector
} else
{
  auto index = std::distance(Names.begin(), it);
}

8
ทำไมไม่ใช้ const-iterators
dani

-1

ฉันเป็นมือใหม่ดังนั้นนี่คือคำตอบสำหรับผู้เริ่มต้น if ใน for loop จะให้ i ซึ่งสามารถใช้ได้ตามต้องการเช่น Numbers [i] ในเวกเตอร์อื่น ส่วนใหญ่เป็นปุยเพื่อประโยชน์ตัวอย่างสำหรับ / ถ้าพูดทั้งหมดจริงๆ

int main(){
vector<string>names{"Sara", "Harold", "Frank", "Taylor", "Sasha", "Seymore"};
string req_name;
cout<<"Enter search name: "<<'\n';
cin>>req_name;
    for(int i=0; i<=names.size()-1; ++i) {
        if(names[i]==req_name){
            cout<<"The index number for "<<req_name<<" is "<<i<<'\n';
            return 0;
        }
        else if(names[i]!=req_name && i==names.size()-1) {
            cout<<"That name is not an element in this vector"<<'\n';
        } else {
            continue;
        }
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.