Hitung kemunculan karakter dalam string dalam C ++


199

Bagaimana saya bisa menghitung jumlah "_"dalam string "bla_bla_blabla_bla"?


17
@jdmichal: "pertanyaan pemula yang kurang ditanyakan"! = "pekerjaan rumah"

@Roger: Tentu saja itu mungkin bukan pekerjaan rumah, tapi ada baiknya mengasumsikan pekerjaan rumahnya setidaknya untuk jawabannya, karena 1) memanjakan pertanyaan pekerjaan rumah itu buruk untuk dipelajari, 2) Anda masih bisa belajar dari "jawaban pekerjaan rumah" yang baik, 3 ) OP dapat (dan harus) memberikan umpan balik dan mengatakan ini bukan pekerjaan rumah
schnaader

3
@ schnaader: Bagaimana jika OP mengatakan ini bukan pekerjaan rumah mereka, bukankah itu masih mungkin pekerjaan rumah bagi orang lain? Haruskah kita "merusaknya" untuk mereka? Dan sebaliknya: seseorang yang baru mengenal C ++ tetapi lama tidak sekolah dapat mengajukan pertanyaan ini; apakah Anda akan memberi mereka jawaban "lengkap"? Mengapa karakteristik poster — ditugaskan oleh guru (pekerjaan rumah) —dikategorikan sebagai konten (label) pertanyaan? Sepertinya semua jawaban di bawah ini, termasuk jawaban Anda dan saya, akan tetap sama terlepas dari tag itu.

@ Roger: Saya akan memberikan jawaban lain jika saya yakin ini bukan pekerjaan rumah. Dalam hal ini saya telah menjawab dengan kode C lengkap alih-alih pseudocode. Dan merusak orang lain tidak begitu penting - jika mereka dapat mencarinya di sini, mereka juga dapat mencari Google. Juga, mencari sesuatu mungkin sebenarnya jauh lebih baik (walaupun bukan yang terbaik) cara belajar daripada hanya memposting pekerjaan rumah Anda dan mendapatkan kode / solusi lengkap beberapa menit kemudian.
schnaader

2
@ schnaader: Ada 32 jawaban di sana dan urutannya bervariasi, yang mana? Apakah Anda pikir saya seharusnya tidak memberikan jawaban "kode lengkap" untuk pertanyaan "pekerjaan rumah" ini ? Sejujurnya, untuk pertanyaan di sini, sangat membantu untuk mendorong pemikiran terlepas dari itu pekerjaan rumah, dan saya suka jawaban Anda jauh lebih baik daripada jika itu memiliki kode C lengkap, karena alasan itu. Anda membantu dengan menjawab pertanyaan, bukan maksud poster yang tidak ada.

Jawaban:


418
#include <algorithm>

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

15
Argumen ketiga adalah tipe char, yaitu, kutipan tunggal, bukan kutipan ganda ...
Emerson Xu

1
Ini jawaban terbaik.
Konchog

Catatan kecil, tetapi jenis pengembalian biasanya ditandatangani. Untuk beberapa alasan std::countjenis hasil iterator_traits<InputIt>::difference_type, yang untuk sebagian besar kontainer standar std::ptrdiff_t, tidak std::size_t.
Daniel Stevens

30

Kodesemu:

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

EDIT: C ++ contoh kode:

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

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

  return count;
}

Perhatikan bahwa ini adalah kode untuk digunakan bersama std::string , jika Anda menggunakan char*, ganti s.size()denganstrlen(s) .

Juga perhatikan: Saya bisa mengerti Anda menginginkan sesuatu "sekecil mungkin", tetapi saya sarankan Anda untuk menggunakan solusi ini sebagai gantinya. Seperti yang Anda lihat, Anda dapat menggunakan fungsi untuk merangkum kode untuk Anda sehingga Anda tidak perlu menulis forloop setiap kali, tetapi hanya dapat digunakan count_underscores("my_string_")di sisa kode Anda. Menggunakan algoritma C ++ yang canggih tentu mungkin di sini, tapi saya pikir itu berlebihan.


24
Tentunya kita dapat membuat versi templated yang sama sekali tidak dapat dibaca dengan fungsi lamba dan panggilan bind2nd ()?
Martin Beckett

@ Martin Saya sebenarnya memikirkan itu. Sayangnya pemahaman saya tentang pemrograman fungsional C ++ praktis tidak ada.
jdmichal

8
Saya pikir memanggil layanan web akan jauh lebih menyenangkan daripada lambdas, maka algoritma inti tidak hanya dapat dipahami, tetapi disimpan di tempat lain.
Ben Voigt

Ini bukan pertanyaan pekerjaan rumah. Saya baru mengenal c ++ dan tidak memiliki cukup pengetahuan tentang c ++ untuk memprogram ini secara lebih lanjut. Baca: sekecil mungkin. Saya dapat memprogram ini secara sederhana dengan for for dan sebagainya, tetapi saya sedang mencari solusi canggih, sesuatu seperti solusi Diego. Lain kali saya akan memberikan lebih banyak informasi untuk alasan pertanyaan.
andre de boer

Selain itu, Anda ingin mengkonsumsi kejadian yang berdekatan jika Anda tidak ingin duplikat. Seperti misalnya, menghitung berapa banyak potongan yang akan Anda dapatkan setelah memisahkan string dengan karakter yang diinginkan.
TheRealChx101

24

Solusi kuno dengan variabel bernama tepat. Ini memberi kode semangat.

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

Sunting: sekitar 8 tahun kemudian, melihat jawaban ini saya malu saya melakukan ini (meskipun saya membenarkannya sendiri sebagai sodokan pada pertanyaan usaha rendah). Ini beracun dan tidak OK. Saya tidak menghapus pos; Saya menambahkan permintaan maaf ini untuk membantu mengubah atmosfer di StackOverflow. Jadi OP: Saya minta maaf dan saya harap Anda mendapatkan pekerjaan rumah Anda dengan benar terlepas dari trolling saya dan jawaban seperti milik saya tidak membuat Anda enggan berpartisipasi di situs.


1
Serius? Jawaban yang sengaja dikaburkan adalah yang terbaik yang dapat Anda lakukan dan Anda pikir itu akan sesuai di sini?

4
@Tamas: int (true) selalu 1 di C ++.

6
solusi kuno benar-benar akan mendeklarasikan prototipe untuk sprintf daripada # termasuk file header keseluruhan !
John Dibling

5
@Tamas: Tentu saja tidak, tapi saya tidak bersenang-senang saat "menjawab" pertanyaan pemula.

11
Suka. Malu itu melanggar aturan garis bawah ganda.
Martin York

13
#include <boost/range/algorithm/count.hpp>

std::string str = "a_b_c";
int cnt = boost::count(str, '_');

10

Sebut saja ... versi Lambda ... :)

using namespace boost::lambda;

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

Anda perlu beberapa termasuk ... Saya meninggalkan Anda itu sebagai latihan ...


7
Apakah Anda benar-benar berpikir seorang pemula akan memahami semua ini?
Josh Stodola

2
@Josh: Tampaknya ini adalah spin-off dari tawa kekanak-kanakan di beberapa komentar .

5
Beberapa programmer top dunia telah menghabiskan 15 tahun terakhir untuk mengembangkan C ++ ke titik di mana kita dapat menulis ini - ini bukan kekanak-kanakan!
Martin Beckett

Membuat titik bahwa mereka yang tidak tahu Perl dipaksa untuk menemukannya kembali (buruk) - sekarang itu kekanak-kanakan!
Martin Beckett

7
Sangat konyol untuk tidak menyertakannya.
PascalVKooten

5

Menggunakan fungsi lambda untuk memeriksa karakter adalah "_" maka hanya jumlah yang akan bertambah jika bukan karakter yang valid

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
Silakan tambahkan penjelasan - cobalah untuk tidak memposting blok kode saja.
Kinerja Tertentu

1
Apa yang Anda pikirkan, yang ditawarkan oleh jawaban Anda, apa yang belum pernah dijawab oleh jawaban sebelumnya? Harap edit dan perluas jawaban Anda.
hellow

1
Terima kasih atas cuplikan kode ini, yang mungkin memberikan bantuan terbatas dan segera. Sebuah penjelasan yang tepat akan sangat meningkatkan nilai jangka panjang dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah ini, dan akan membuatnya lebih bermanfaat untuk pembaca masa depan dengan lainnya, pertanyaan-pertanyaan serupa. Harap edit jawaban Anda untuk menambahkan beberapa penjelasan, termasuk asumsi yang Anda buat.
Tim Diekmann

Digunakan fungsi lambda untuk memeriksa karakter adalah "_" maka hanya jumlah yang akan bertambah jika bukan karakter yang valid.
Nagappa

[]( char c ){if(c =='_') return true; }memanggil perilaku yang tidak terdefinisi karena Anda tidak mengembalikan nilai di semua jalur kode
phuclv

4

Ada beberapa metode std :: string untuk pencarian, tetapi menemukan mungkin adalah yang Anda cari. Jika yang Anda maksud adalah string gaya-C, maka padanannya adalah strchr. Namun, dalam kedua kasus tersebut, Anda juga dapat menggunakan loop for dan memeriksa setiap karakter — loop pada dasarnya adalah apa yang mereka bungkus.

Setelah Anda tahu bagaimana menemukan karakter berikutnya yang diberi posisi awal, Anda terus memajukan pencarian Anda (yaitu menggunakan loop), menghitung saat Anda pergi.


4

Menghitung kemunculan karakter dalam string mudah:

#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 Ini sama dengan jawaban teratas yang ada dari enam tahun sebelumnya - apa maksudnya ini ditambahkan? Ada satu perbedaan: jawaban ini menggunakan file header yang salah. stdc ++. h khusus untuk GCC, dan bahkan dengan kompiler itu hanya dimaksudkan untuk digunakan dalam header yang dikompilasi.
Arthur Tacca


2

Anda dapat mengetahui kemunculan '_' dalam string sumber dengan menggunakan fungsi string. fungsi find () membutuhkan 2 argumen, string pertama yang kemunculannya ingin kita ketahui dan argumen kedua mengambil posisi awal. Sementara loop digunakan untuk mengetahui kejadian sampai akhir string sumber.

contoh:

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

Saya akan melakukan ini:

#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;
}

Ya tentu saja, dan sebenarnya saya melakukan itu, tetapi idk bagaimana itu kacau ketika saya menyalinnya dari Visual Studio ke bentuk SO.
Shivam Jha

0

Saya akan melakukan sesuatu seperti itu :)

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

-3

Mencoba

#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
Aduh! Bahasa yang salah.
Lightness Races in Orbit
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.