นับจำนวนอักขระที่เกิดขึ้นในสตริงใน C ++


199

ฉันจะนับจำนวน"_"ในสตริงได้"bla_bla_blabla_bla"อย่างไร


17
@jdmichal: "คำถามเริ่มต้นที่ถามไม่ดี"! = "การบ้าน"

@Roger: แน่นอนว่ามันอาจจะไม่ใช่การบ้าน แต่มันเป็นการดีที่จะทำการบ้านอย่างน้อยสำหรับคำตอบเพราะ 1) การทำลายคำถามการบ้านนั้นไม่ดีสำหรับการเรียนรู้ 2) คุณยังสามารถเรียนรู้ได้จาก "คำตอบการบ้าน" ที่ดี ) OP สามารถ (และควร) ให้ข้อเสนอแนะและบอกว่านี่ไม่ใช่การบ้าน
schnaader

3
@schnaader: ถ้า OP บอกว่านี่ไม่ใช่การบ้านของพวกเขามันยังมีแนวโน้มที่จะทำการบ้านให้คนอื่นไม่ได้เหรอ? เราควร "ทำลาย" เพื่อพวกเขาหรือไม่? และในทางกลับกัน: บางคนที่เพิ่งเริ่มเรียนภาษา C ++ แต่ไม่ได้เรียนนานอาจถามคำถามนี้ คุณจะให้คำตอบ "สมบูรณ์" ให้พวกเขาหรือไม่ เหตุใดคุณลักษณะของโปสเตอร์ - ที่ได้รับมอบหมายโดยครู (ทำการบ้าน) - เป็นหมวดหมู่ของเนื้อหาของคำถาม (แท็ก) ดูเหมือนว่าคำตอบทั้งหมดด้านล่างรวมถึงทั้งของคุณและของฉันจะเหมือนกันโดยไม่คำนึงถึงแท็กนั้น

@ Roger: ฉันจะได้รับคำตอบอีกแน่นอนถ้าฉันแน่ใจว่านี่ไม่ใช่การบ้าน ในกรณีนี้ฉันตอบด้วยรหัส C สมบูรณ์แทนรหัสเทียม และการทำให้คนอื่นเสียไม่สำคัญอย่างนั้น - หากพวกเขาสามารถค้นหาได้ที่นี่พวกเขาสามารถค้นหา Google ได้เช่นกัน นอกจากนี้การค้นหาบางสิ่งอาจเป็นวิธีที่ดีกว่า (แม้ว่าจะไม่ใช่วิธีที่ดีที่สุด) ในการเรียนรู้มากกว่าแค่โพสต์การบ้านของคุณและรับรหัส / โซลูชันที่สมบูรณ์ในไม่กี่นาทีต่อมา
schnaader

2
@schnaader: มี 32 คำตอบและเรียงลำดับแตกต่างกันไปที่หนึ่ง? คุณคิดว่าฉันไม่ควรให้คำตอบ "รหัสสมบูรณ์" สำหรับคำถาม"homework-esque" นี้หรือไม่? เพื่อความซื่อสัตย์อย่างสมบูรณ์สำหรับคำถามที่นี่จะเป็นประโยชน์ในการส่งเสริมความคิดโดยไม่คำนึงถึงว่าเป็นการทำการบ้านและฉันชอบคำตอบของคุณดีกว่าถ้ามันมีรหัส C ครบถ้วนด้วยเหตุผลนั้น คุณมีประโยชน์โดยตอบคำถามไม่ใช่เจตนาภายนอกของโปสเตอร์

คำตอบ:


418
#include <algorithm>

std::string s = "a_b_c";
size_t n = std::count(s.begin(), s.end(), '_');

15
อาร์กิวเมนต์ที่สามเป็นชนิดถ่านคือคำพูดเดียวไม่ได้ราคาคู่ ...
เมอร์สัน Xu

1
นี่คือคำตอบที่ดีที่สุด
Konchog

บันทึกย่อขนาดเล็ก แต่โดยทั่วไปแล้วประเภทส่งคืนจะถูกเซ็นชื่อ ด้วยเหตุผลบางstd::countประเภทผลตอบแทนiterator_traits<InputIt>::difference_typeซึ่งสำหรับภาชนะมาตรฐานมากที่สุดคือไม่std::ptrdiff_t std::size_t
Daniel Stevens

30

pseudocode:

count = 0
For each character c in string s
  Check if c equals '_'
    If yes, increase count

แก้ไข: รหัสตัวอย่าง C ++:

int count_underscores(string s) {
  int count = 0;

  for (int i = 0; i < s.size(); i++)
    if (s[i] == '_') count++;

  return count;
}

โปรดทราบว่านี่คือรหัสที่จะใช้ร่วมกับstd::stringหากคุณใช้char*ให้แทนที่s.size()ด้วยstrlen(s)ด้วย

หมายเหตุเพิ่มเติม: ฉันเข้าใจว่าคุณต้องการบางสิ่งที่ "เล็กที่สุด" แต่ฉันแนะนำให้คุณใช้วิธีนี้แทน ดังที่คุณเห็นคุณสามารถใช้ฟังก์ชั่นเพื่อห่อหุ้มรหัสให้คุณดังนั้นคุณไม่จำเป็นต้องเขียนforลูปทุกครั้ง แต่สามารถใช้count_underscores("my_string_")ในส่วนที่เหลือของรหัสได้ การใช้อัลกอริทึม C ++ ขั้นสูงเป็นไปได้อย่างแน่นอนที่นี่ แต่ฉันคิดว่ามันเกินความจริง


24
แน่นอนว่าเราสามารถสร้างเวอร์ชั่นที่ไม่สามารถอ่านได้ด้วยฟังก์ชั่น lamba และการโทร bind2nd ()?
Martin Beckett

@ มาร์ตินฉันคิดอย่างนั้นจริงๆ น่าเสียดายที่ความเข้าใจของฉันในการเขียนโปรแกรมฟังก์ชั่น C ++ นั้นแทบไม่มีอยู่จริง
jdmichal

8
ฉันคิดว่าการโทรหาบริการบนเว็บจะสนุกกว่า lambdas มากไปกว่านั้นอัลกอริธึมหลักไม่ได้เป็นเพียงการแบ่งแยก แต่มันถูกเก็บไว้ที่อื่น
Ben Voigt

นี่ไม่ใช่คำถามทำการบ้าน ฉันใหม่กับ c ++ และไม่มีความรู้เพียงพอในการเขียนโปรแกรม c ++ ในลักษณะขั้นสูง อ่าน: เล็กที่สุด ฉันสามารถเขียนโปรแกรมในลักษณะที่เรียบง่ายด้วย for for loop และอื่น ๆ แต่ฉันกำลังมองหาโซลูชันที่ซับซ้อนบางอย่างเช่นโซลูชันของ Diego ครั้งต่อไปฉันจะให้ข้อมูลเพิ่มเติมด้วยเหตุผลของคำถาม
อังเดรบัวร์

นอกจากนี้คุณต้องการใช้สิ่งที่เกิดขึ้นอย่างต่อเนื่องในกรณีที่คุณไม่ต้องการทำซ้ำ เช่นนับจำนวนชิ้นที่คุณจะได้รับหลังจากแยกสตริงด้วยตัวละครที่ต้องการ
TheRealChx101

24

โซลูชันที่ล้าสมัยพร้อมตัวแปรที่ตั้งชื่ออย่างเหมาะสม สิ่งนี้ทำให้โค้ดมีวิญญาณ

#include <cstdio>
int _(char*__){int ___=0;while(*__)___='_'==*__++?___+1:___;return ___;}int main(){char*__="_la_blba_bla__bla___";printf("The string \"%s\" contains %d _ characters\n",__,_(__));}

แก้ไข: ประมาณ 8 ปีต่อมาโดยดูที่คำตอบนี้ฉันรู้สึกละอายใจที่ฉันทำสิ่งนี้ (แม้ว่าฉันจะให้เหตุผลกับตัวเองว่าเป็นคนขี้ขลาดเย้ายวนใจด้วยคำถามที่ใช้ความพยายามต่ำ) นี่เป็นพิษและไม่เป็นไร ฉันไม่ได้ลบโพสต์ ฉันกำลังเพิ่มคำขอโทษนี้เพื่อช่วยเปลี่ยนบรรยากาศใน StackOverflow ดังนั้น OP: ฉันขอโทษและฉันหวังว่าคุณจะได้รับการบ้านของคุณแม้จะมีการหลอกและคำตอบที่ฉันชอบไม่ได้กีดกันคุณจากการเข้าร่วมในเว็บไซต์


1
อย่างจริงจัง? คำตอบที่ยุ่งเหยิงอย่างมีจุดประสงค์คือสิ่งที่ดีที่สุดที่คุณสามารถทำได้และคุณคิดว่ามันจะเหมาะสมหรือไม่?

4
@Tamas: int (จริง) เสมอ 1 ใน C ++

6
โซลูชันแบบเก่าที่แท้จริงจะประกาศต้นแบบสำหรับ sprintf แทนที่จะเป็น # รวมถึงไฟล์ส่วนหัวทั้งหมด !
John Dibling

5
@ Tamas: ไม่แน่นอน แต่ฉันไม่มีความสนุกในขณะที่ตอบคำถาม "มือใหม่"

11
รักมัน ความอัปยศมันเป็นการละเมิดกฎขีดเส้นใต้คู่
Martin York


10

คุณชื่อมัน ... รุ่นแลมบ์ดา ... :)

using namespace boost::lambda;

std::string s = "a_b_c";
std::cout << std::count_if (s.begin(), s.end(), _1 == '_') << std::endl;

คุณต้องมีหลาย ... ฉันปล่อยให้คุณเป็นแบบฝึกหัด ...


7
คุณคิดว่ามือใหม่จะเข้าใจสิ่งนี้หรือไม่?
Josh Stodola

2
@ Josh: มันดูเหมือนจะเป็นมะเร็งของเสียงหัวเราะหน่อมแน้มในบางความคิดเห็น

5
โปรแกรมเมอร์ชั้นนำของโลกบางคนใช้เวลา 15 ปีที่ผ่านมาในการพัฒนา C ++ ไปจนถึงจุดที่เราสามารถเขียนสิ่งนี้ - มันไม่ใช่เรื่องไร้สาระ!
Martin Beckett

ชี้ให้เห็นว่าผู้ที่ไม่ทราบว่า Perl ถูกบังคับให้ต้องคิดค้นสิ่งใหม่ (ไม่ดี) - ตอนนี้น่าจะเป็นเรื่องไร้สาระ!
Martin Beckett

7
มันไร้สาระที่จะปล่อยให้รวมถึง
PascalVKooten

5

การใช้ฟังก์ชั่นแลมบ์ดาเพื่อตรวจสอบอักขระคือ "_" จากนั้นจำนวนเฉพาะจะเพิ่มขึ้นมิฉะนั้นจะไม่ใช่อักขระที่ถูกต้อง

std::string s = "a_b_c";
size_t count = std::count_if( s.begin(), s.end(), []( char c ){if(c =='_') return true; });
std::cout << "The count of numbers: " << count << std::endl;

2
โปรดเพิ่มคำอธิบาย - พยายามอย่าโพสต์เพียงแค่บล็อกธรรมดา ๆ ของรหัสเพียงอย่างเดียว
ดำเนินงาน CertainPerformance

1
คุณคิดว่าคำตอบของคุณมีอะไรคำตอบก่อนหน้านี้ยังไม่ครอบคลุม โปรดแก้ไขและขยายคำตอบของคุณ
สวัสดี

1
ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติฐานที่คุณทำ
ทิม Diekmann

ใช้ฟังก์ชั่นแลมบ์ดาเพื่อตรวจสอบตัวละครว่า "_" จากนั้นจำนวนเฉพาะจะเพิ่มขึ้นมิฉะนั้นจะไม่ใช่อักขระที่ถูกต้อง
Nagappa

[]( char c ){if(c =='_') return true; }เรียกใช้พฤติกรรมที่ไม่ได้กำหนดเนื่องจากคุณไม่ได้ส่งคืนค่าในทุกเส้นทางของรหัส
phuclv

4

มีหลายวิธีในการ std :: string สำหรับการค้นหา แต่ find อาจเป็นสิ่งที่คุณกำลังมองหา หากคุณหมายถึงสตริงแบบ C ค่าที่เทียบเท่าคือ strchr อย่างไรก็ตามในกรณีใดกรณีหนึ่งคุณยังสามารถใช้ for for loop และตรวจสอบอักขระแต่ละตัว - loop นั้นเป็นสิ่งที่ทั้งสองสรุปไว้

เมื่อคุณรู้วิธีค้นหาตัวละครตัวต่อไปที่ได้รับตำแหน่งเริ่มต้นคุณจะต้องค้นหาต่อไปอย่างต่อเนื่อง (เช่นใช้วง) นับตามที่คุณไป


4

นับจำนวนตัวอักษรในสตริงเป็นเรื่องง่าย:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s="Sakib Hossain";
    int cou=count(s.begin(),s.end(),'a');
    cout<<cou;
}

1
-1 นี่เหมือนกับคำตอบยอดนิยมที่มีอยู่เมื่อหกปีก่อน - นี่หมายถึงอะไรเพิ่ม ข้อแตกต่าง: คำตอบนี้ใช้ไฟล์ส่วนหัวที่ไม่ถูกต้อง stdc ++. h มีความเฉพาะกับ GCC และแม้กระทั่งกับคอมไพเลอร์นั้นมันมีไว้สำหรับใช้ในส่วนหัวที่คอมไพล์แล้วเท่านั้น
Arthur Tacca


2

คุณสามารถค้นหาการเกิดขึ้นของ '_' ในสตริงต้นฉบับโดยใช้ฟังก์ชันสตริง find () ฟังก์ชั่นใช้เวลา 2 ข้อโต้แย้งครั้งแรก - สตริงที่เกิดขึ้นที่เราต้องการที่จะหาและอาร์กิวเมนต์ที่สองจะใช้ตำแหน่งเริ่มต้นในขณะที่ห่วงจะใช้ในการหาการเกิดขึ้นจนถึงจุดสิ้นสุดของสตริงที่มา

ตัวอย่าง:

string str2 = "_";
string strData = "bla_bla_blabla_bla_";

size_t pos = 0,pos2;

while ((pos = strData.find(str2, pos)) < strData.length()) 
{
    printf("\n%d", pos);
    pos += str2.length();
} 

2

ฉันจะทำแบบนี้:

#include <iostream>
#include <string>
using namespace std;
int main()
{

int count = 0;
string s("Hello_world");

for (int i = 0; i < s.size(); i++) 
    {
       if (s.at(i) == '_')    
           count++;
    }
cout << endl << count;
cin.ignore();
return 0;
}

ใช่แน่นอนและในความเป็นจริงฉันทำอย่างนั้น แต่ idk ว่ามันเลอะอย่างไรเมื่อฉันคัดลอกจาก Visual Studio ไปยังรูปแบบ SO
Shivam Jha

0

ฉันจะทำอะไรแบบนั้น :)

const char* str = "bla_bla_blabla_bla";
char* p = str;    
unsigned int count = 0;
while (*p != '\0')
    if (*p++ == '_')
        count++;

-3

ลอง

#include <iostream>
 #include <string>
 using namespace std;


int WordOccurrenceCount( std::string const & str, std::string const & word )
{
       int count(0);
       std::string::size_type word_pos( 0 );
       while ( word_pos!=std::string::npos )
       {
               word_pos = str.find(word, word_pos );
               if ( word_pos != std::string::npos )
               {
                       ++count;

         // start next search after this word 
                       word_pos += word.length();
               }
       }

       return count;
}


int main()
{

   string sting1="theeee peeeearl is in theeee riveeeer";
   string word1="e";
   cout<<word1<<" occurs "<<WordOccurrenceCount(sting1,word1)<<" times in ["<<sting1 <<"] \n\n";

   return 0;
}

-4
public static void main(String[] args) {
        char[] array = "aabsbdcbdgratsbdbcfdgs".toCharArray();
        char[][] countArr = new char[array.length][2];
        int lastIndex = 0;
        for (char c : array) {
            int foundIndex = -1;
            for (int i = 0; i < lastIndex; i++) {
                if (countArr[i][0] == c) {
                    foundIndex = i;
                    break;
                }
            }
            if (foundIndex >= 0) {
                int a = countArr[foundIndex][1];
                countArr[foundIndex][1] = (char) ++a;
            } else {
                countArr[lastIndex][0] = c;
                countArr[lastIndex][1] = '1';
                lastIndex++;
            }
        }
        for (int i = 0; i < lastIndex; i++) {
            System.out.println(countArr[i][0] + " " + countArr[i][1]);
        }
    }

1
อ๊ะ! ภาษาผิด
การแข่งขัน Lightness ใน Orbit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.