2010-01-24 17 views
6

मैं कैसे कर सकता हूँ ताकि अंतिम खिलाड़ी नाम एक , नहीं है तो यह है:लूप के दौरान सी ++ में अंतिम पुनरावृत्ति को मैं कैसे पहचान सकता हूं?

Player online: 
Jim, John, Tony 

और नहीं

Player online: 
Jim, John, Tony, 

मेरे कोड है:

bool Commands::whoIsOnline(Creature* c, const std::string &cmd, const std::string &param) 
{ 
Player* player = dynamic_cast<Player*>(c); 

if (player) 
{ 
    player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Players online: "); 
    AutoList<Player>::listiterator iter = Player::listPlayer.list.begin(); 
    std::string info; 
    int count = 0; 

    while (iter != Player::listPlayer.list.end()) 
    { 
     info += (*iter).second->getName() + ", "; 
     ++iter; 
     ++count; 

     if (count % 10 == 0) 
     { 
      player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str()); 
      info.clear(); 
     } 
    } 

    if (!info.empty()) 
     player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str()); 
} 

return true; 
} 
+0

पिछले यात्रा को पहचान, पाश अंदर पाश की स्थिति की जांच करने के लिए। –

उत्तर

4

परिवर्तन

while(iter != Player::listPlayer.list.end()) 
{ 
    info += (*iter).second->getName() + ", "; 
//... 

साथ:

if(iter != Player::listPlayer.list.end()){ 
    info += (*iter).second->getName(); 
    ++iter; 
    while(iter != Player::listPlayer.list.end()){ 
    { 
     info += ", " + (*iter).second->getName();  
     //... 
    } 
    //... 
} 

वैकल्पिक रूप से, आप कुछ इस तरह कर सकते हैं यदि आप नहीं है एक नाम के सामने अल्पविराम info.clear() के बाद हैं:

while(iter != Player::listPlayer.list.end()) 
{ 
    info += ", " + (*iter).second->getName(); 
    // ... 
     player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str()+2); 
+2

मैं इस दृष्टिकोण का उपयोग करता हूं, लेकिन if-statement के लिए अधीनस्थ-लूप अधीनस्थ बना देता हूं। अगर ऐसा नहीं होता है तो समय का पहला टेस्ट सफल नहीं होगा। – Boojum

+0

@ बुजुम, अच्छी कॉल, मैं उचित रूप से –

2

सबसे आसान तरीका

if (!info.empty()) { 
    info.erase(info.size()-2); 
} 
0

आप cou यदि यह सी ++ है और अगर इटरेटर एक यादृच्छिक अभिगम इटरेटर है कि एक एसटीएल इटरेटर है, तो, तो: बस अतिरिक्त ", " अंत में दूर करने के लिए है ld वास्तव में पूछना

अगर (आईटीईआर + 1 == Plaer :: listPlayer.list.end())

आप ऐसा करने की अनुमति नहीं कर रहे हैं, तो आप शायद उस कोड को उस लूप के अंदर रखना चाहते हैं जो किसी खिलाड़ी के नाम को एक अलग फ़ंक्शन में प्रिंट करता है और उस लूप को पहले तत्व पर लूप से पहले कॉल करता है, फिर उसे लूप के अंदर कॉल करें। फिर उस कोड को रखें जो कॉल लूप में प्लेयर नाम प्रिंट पर कॉल से पहले कॉमा प्रिंट करता है। इस तरह पहला कॉल केवल पहले नाम को प्रिंट करेगा, और फिर थोड़ी देर लूप हमेशा पहले कॉमा प्रिंट करेगा और उसके बाद प्लेयर का नाम प्रिंट करेगा, ताकि आउटपुट हमेशा प्लेयर के नाम से समाप्त हो। के रूप में "," + player

इसके बारे में player + "," थिंक जैसे कि यह सोच की

7

इसके बजाय तो आप इस (छद्म-कोड) की तरह कुछ कर सकता है:

onFirstName = true 
output = "" 
for each player in players: 
    if onFirstName: 
     onFirstName = false 
    else: 
     output += ", " 
    output += player's name 
अपनी भाषा इसका समर्थन करता है, तो के

(जो C++ करता है) :

if length of players > 0: 
    output = players[0] 
    for each player in players except players[0]: 
     output += ", " + player's name 
else: 
    output = "" 

मुझे उस आखिरी व्यक्ति की तलाश पसंद है, मुझे उस भाषा का आविष्कार करना होगा जो वास्तव में ऐसा काम करता है।

http://www.taenarum.com/csua/fun-with-c/delimiter.c

दुर्भाग्य से, वहाँ कोई विधि नहीं है:

+0

संपादित करूँगा, यह केवल खिलाड़ियों पर केवल पुनरावृत्ति करने के लिए बहुत तेज होगा 2.। (यदि वे मौजूद हैं)। अगर केवल किसी ने सुझाव दिया था कि .. –

+0

यह वास्तव में होगा। मैंने सी ++ इटरेटर्स का कभी भी उपयोग नहीं किया है, मुझे नहीं पता था कि आप उनके साथ ऐसा कर सकते हैं। – Ponkadoodle

+0

मेरे उत्तर पर एक नज़र डालें =) आपको पहले मान को देखने के बाद बस वृद्धि करने की आवश्यकता है। –

2

(उधार wallacoloo के स्यूडोकोड)

output = "" 
for each player in players: 
    if output != "" 
     output += ", " 
    output += player's name 
+1

बस wallacoloo के कोड की तरह, यदि आप लूप के बाहर पहले खिलाड़ी को देखते हैं तो आपका बहुत तेज होगा, इस तरह आप हर दूसरे खिलाड़ी के लिए अगर कथन नहीं मारते हैं ... –

+0

गंभीरता से, "बहुत तेज़"? कितना? 25% से कम या कम? –

+0

हां, लेकिन: आप लूप के बाहर और अंदर समान कोड डुप्लिकेट करेंगे (कल्पना करें कि आपको प्लेयर के नाम को देखना या प्रारूप करना था), और: नल के विरुद्ध तुलना करना आमतौर पर बहुत अनुकूल है। –

0

मैं सी में ऐसा करने का कुछ भिन्न तरीकों से प्रदर्शित करने के लिए कुछ समय पहले कुछ नमूना कोड लिखा था यह दूसरों के लिए स्पष्ट रूप से बेहतर है।स्पष्ट रूप से और डुप्लिकेटिंग कोड से बचने के लिए मैं व्यक्तिगत रूप से एक पारंपरिक दृष्टिकोण (स्पष्ट रूप से पहले या अंतिम तत्व की जांच कर सकता हूं) के साथ जाऊंगा। (और निश्चित रूप से C12+ कोड में goto संस्करण का उपयोग करने से बचें।)

1

यदि यह मेरा कोड था, तो शायद मैं लूप की शुरुआत में स्ट्रिंग की जांच करूँगा और जब यह खाली नहीं होगा तो अल्पविराम जोड़ें। यह पता है कि कैसे ऐसी ही स्थितियों को संभालने के लिए जब कि वैकल्पिक हल उपलब्ध नहीं है अच्छा है इसलिए यहाँ एक वैकल्पिक है:

while (iter != Player::listPlayer.list.end()) 
{ 
    info += (*iter).second->getName(); 
    ++iter; 
    if (iter != Player::listPlayer.list.end()) 
     info += ", "; 
    ++count; 
    ... 
} 
2

आप स्ट्रिंग नेट से शामिल होने या बढ़ावा या कुछ अन्य पुस्तकालय या अपने खुद के बारे में उपयोग कर सकते हैं। यद्यपि यह उस विशेष कार्य के लिए अधिक हो सकता है, यह ऐसी चीज है जिसे आप शायद उस परियोजना में कहीं और उपयोग करेंगे, और आप निश्चित रूप से किसी अन्य प्रोजेक्ट में पुन: उपयोग करेंगे।

1

अंतिम पुनरावृत्ति खोजने के बजाय, पहला पुनरावृत्ति पाएं। लूप की शुरुआत में विशेष मामलों को संभालें, "असली काम" करने से पहले एक निश्चित "साफ" स्थिति रखें और अंत में वृद्धि करें।

while (iter != Player::listPlayer.list.end()) 
{ 
    if (count != 0) 
    { 
     info += ", "; 

     if (count % 10 == 0) 
     { 
      player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str()); 
      info.clear(); 
     } 
    } 
    // invariant: info is clean and ready to accept data 

    info += (*iter).second->getName(); 
    ++iter; 
    ++count; 
} 
1

मेरे समाधान एक चर कि रिक्त स्ट्रिंग के रूप में बाहर शुरू होता है और प्रत्येक यात्रा के बाद ", " पर सेट है (केवल पहली यात्रा के बाद एक प्रभाव है) शामिल है। कोई विशेष मामलों की जांच की जरूरत नहीं है।

template<class ForwardIterator> 
std::string sequence_to_string(ForwardIterator begin, ForwardIterator end) 
{ 
    std::string output; 
    const char* delimiter = ""; 
    for (ForwardIterator it = begin; it != end; ++it) 
    { 
     output += delimiter; 
     output += *it; 
     delimiter = ", "; 
    } 
    return output; 
} 
0
...  
std::string info; 
... 
while (iter != Player::listPlayer.list.end()) 
{ 
    if(info.size() > 0) 
    info += ","; 
    info += (*iter).second->getName(); 
    ...... 
} 
संबंधित मुद्दे