PDA

View Full Version : استفاده از std::map بصورت اندیسی



pswin.pooya
دوشنبه 23 شهریور 1388, 14:12 عصر
سلام
چطور میتونم با دادن اندیس به std::map ازش استفاده کنم. مثلا فرض کنید که من یه std::map به صورت زیر دارم که با استفاده از key به راحتی میتونم ازش استفاده کنم و داده ها رو بگیرم:



std::map<std::string, float> m_ map;
m_map["val1"] = 1.2;
std::cout << m_map["val1"] << std::endl;


حالا به جای دادن key میخوام از اندیس ها استفاده کنم. به عنوان مثال میخوام به اولین مورد داخلش به صورت m_map[0] دسترسی پیدا کنم و دیگه یک key از نوع رشته بهش ندم.

Nima_NF
دوشنبه 23 شهریور 1388, 18:52 عصر
برای دسترسی به تک تک خانه های کلاس های STL همیشه باید از iterator ها یا همان شمارنده ها استفاده کرد، چون هر خانه طول متفاوتی دارد و توسط iterator دقیق طول تعیین می شود.

مثلا به این شکل:



#include <map>
#include <iostream>
#include <string>


map<std::string, float> m_map;
map <std::string, float>::iterator m_Iter;

m_map["val1"] = (float)1.2;


m_Iter = m_map.begin( );

cout << "The first:" << (m_Iter->first).c_str() << endl;
cout << "The first:" << m_Iter->second << endl;

// m_Iter++;
// get next element


شمارنده برای map دو حالت first و second دارد، first مقدار key را می دهد و second مقدار ذخیره شده داده شما که همان 1.2 هست.

pswin.pooya
سه شنبه 24 شهریور 1388, 01:28 صبح
مشکل همیجاست که مرتبا باید iterator اول (begin) گرفته بشه و مرتبا جلو بره. به عنوان مثال من توی کلاس مش موتورم یک تابع به صورت زیر دارم


Mesh* getSubMesh(std::string name);
Mesh* getSubMesh(unsigned int index(;و


std::map<std::string,Mehs*> m_SubMeshesحالا اگر یوزر بخواد sub-mesh رو بگیره خیلی راحت میتونه اسم رو بده. ولی اگر رندرر بخواد مش رو رسم کنه از اندیس استفاده میکنه که نتیجتا برای هر اندیسی صدا میکنه یک حلقه دیگه داخلی فراخوانی میشه و به جای اینکه هزینه n باشه میشه n^2 .


راه حلی برای افزایش سرعت گرفتن اشاره گر sub-meshها از m_SubMEshes به نظرتون میرسه؟؟

Nima_NF
سه شنبه 24 شهریور 1388, 13:20 عصر
این طوری فکر نکنید که وقتی از اندیس استفاده می کنید فقط یک خط کد اجرا می شود و به مقصد می رسید. در حقیقت عملگر [] برای کلاس تعریف شده تا شما را به مقصد برساند.

پس شما برای اینکه خودتان توسط iterator ها به مقصد برسید همیشه نیاز نیست مدام یکی یکی جلو بروید، بلکه این طوری می توانید عمل کنید:




m_Iter = m_map.begin( );

m_Iter +=100; // = myinfo[100]

// use it or get it now
(m_Iter->first).c_str()

اگر یک تابع برای آن بنویسید، راحت می توانید جایگزین اندیس کنید.
دقت کنید که begin چیز خاص و هزینه برداری نیست جز اینکه یک آدرس را می گیرید.
سپس لازم نیست با ++ جلو بروید، فقط مساوی عدد قرار ندهید، یعنی جمع کنید (همان طوری که می خواهید به حافظه ها دسترسی پیدا کنید) یعنی:



m_Iter = m_map.begin( );

m_Iter +=100;
// or
m_Iter = m_Iter + 100;