C ++ 'da bir dizede karakter oluşumlarını sayma


199

"_"Bir dizedeki sayısını nasıl sayabilirim "bla_bla_blabla_bla"?


17
@jdmichal: "kötü sorulan başlangıç ​​sorusu"! = "ödev"

@Roger: Tabii ki belki de ödev değil, ama en azından cevaplar için ödevini üstlenmek iyidir, çünkü 1) bir ödev sorusunu bozmak öğrenme için kötüdür, 2) yine de iyi "ödev cevaplarından" öğrenebilirsiniz, 3 ) OP geribildirim verebilir (ve yapmalıdır) ve bunun bir ev ödevi olmadığını söyleyebilir
schnaader

3
@schnaader: Eğer OP bunun kendi ödevleri olmadığını söylüyorsa, başka biri için hala ödev olması muhtemel değil mi? Onlar için "mahvetmeli miyiz?" Ve tersi: C ++ 'da yeni olan ancak okul dışında uzun süredir bu soruyu sorabilir; onlara "tam" bir cevap verir misiniz? Neden posterin bir özelliği (bunu bir öğretmen tarafından atandı (ödev)) soru içeriğinin (etiketlerinin) bir kategorilendirmesi olmalı? Hem sizin hem de benimki de dahil olmak üzere aşağıdaki tüm cevaplar bu etikete bakılmaksızın aynı olurdu.

@ Roger: Bunun ödev olmadığından emin olsaydım gerçekten başka bir cevap verirdim. Bu durumda yalancı kod yerine tam C kodu ile cevap vermiştim. Ve diğer insanları şımartmak o kadar da kritik değildir - burada arayabilirlerse Google'da da arama yapabilirler. Ayrıca, bir şeyi aramak, ödevinizi göndermekten ve birkaç dakika sonra tam kod / çözümler elde etmekten çok daha iyi (en iyi olmasa da) öğrenmenin yolu olabilir.
schnaader

2
@schnaader: Orada 32 cevap var ve sıralama düzeni değişiyor, hangisi? Sizce bu "ödev-esque" sorusu için "tam kod" cevabı vermemeliydim ? Tamamen dürüst olmak gerekirse, buradaki soru için, ödev olmasına bakılmaksızın düşünceyi teşvik etmek yardımcı olur ve bu nedenle cevabınızı tam C koduna sahip olmaktan çok daha iyi seviyorum. Afişin yabancı amacı değil, soruya cevap vererek yardımcı oluyorsunuz .

Yanıtlar:


419
#include <algorithm>

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

15
Üçüncü argüman bir char tipi, yani tek tırnak, çift tırnak değil ...
Emerson Xu

1
Bu en iyi cevap.
Konchog

Küçük not, ancak dönüş türü genellikle imzalanır. Bazı sebeple std::countdöner tip iterator_traits<InputIt>::difference_typeçoğu standart konteynerlerin içindir std::ptrdiff_t, değil std::size_t.
Daniel Stevens

30

pseudocode:

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

EDIT: C++ example code:

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

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

  return count;
}

Bu kodun, std::string, if you're using char*, replace s.size() with strlen(s).

Also note: I can understand you want something "as small as possible", but I'd suggest you to use this solution instead. As you see you can use a function to encapsulate the code for you so you won't have to write out the for loop everytime, but can just use count_underscores("my_string_") in the rest of your code. Using advanced C++ algorithms is certainly possible here, but I think it's overkill.


24
Şüphesiz, lamba işlevlerine ve bir bind2nd () çağrısına sahip tamamen okunamayan şablonlu bir sürüm bulabilir miyiz?
Martin Beckett

@ Martin aslında bunu düşünüyordum. Ne yazık ki C ++ fonksiyonel programlamayı kavramak neredeyse hiç yok.
jdmichal

8
Bir web hizmeti çağırmak lambdas daha çok daha eğlenceli olacağını düşünüyorum, o zaman çekirdek algoritması sadece anlaşılmaz değil, başka bir yerde saklanır.
Ben Voigt

Bu bir ödev sorusu değil. C ++ için yeniyim ve bunu gelişmiş bir şekilde programlamak için yeterli c ++ bilgisine sahip değilim. Okuyun: mümkün olduğunca küçük. Bunu bir for döngüsü ve benzeri ile basit bir şekilde programlayabiliyorum, ancak Diego'nun çözümü gibi sofistike bir çözüm arıyordum. Bir dahaki sefere sorunun nedeni hakkında daha fazla bilgi vereceğim.
andre de boer

Ayrıca, kopya istemediğiniz takdirde bitişik olayları tüketmek istersiniz. Örneğin, bir dizeyi istenen karaktere böldükten sonra kaç parça alacağınızı saymak gibi.
TheRealChx101

24

Uygun şekilde adlandırılmış değişkenlerle eski moda çözüm. Bu koda biraz ruh verir.

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

Düzenleme: yaklaşık 8 yıl sonra, bu cevaba bakarak ben bunu yaptım utanıyorum (düşük çaba sorusunda sinsi bir dürtmek olarak kendime haklı olsa bile). Bu toksiktir ve TAMAM değildir. Gönderiyi kaldırmıyorum; StackOverflow atmosfer değiştirmeye yardımcı olmak için bu özür ekliyorum. O halde OP: Özür dilerim ve umarım trollingime rağmen ödevini doğru bulmuşsundur ve benimki gibi cevaplar siteye katılmanı cesaretlendirmedi.


1
Ciddi anlamda? Makul bir şekilde gizlenmiş bir cevap yapabileceğiniz en iyisidir ve bunun burada uygun olacağını düşünüyor musunuz?

4
@Tamas: int (true) C ++ 'da her zaman 1'dir.

6
gerçekten eski moda bir çözüm # başlık dosyası yerine # sprintf için bir prototip beyan eder !
John Dibling

5
@Tamas: Tabii ki hayır, ama yeni başlayanların sorularını "cevaplarken" eğlenmiyorum.

11
Sevdim. Utanç çift alt çizgi kuralını ihlal.
Martin York

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

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

10

Siz adlandırın ... Lambda versiyonu ... :)

using namespace boost::lambda;

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

Birkaç içeriğe ihtiyacınız var ... Bunu bir egzersiz olarak bırakıyorum ...


7
Gerçekten bir acemi bunların herhangi birini anlayacağını düşünüyor musun?
Josh Stodola

2
@Josh: It appears to be a spinoff of the childish laughter in some comments.

5
Some of the world's top programmers have spent the last 15years evolving C++ to the point where we can write this - it's not childish!
Martin Beckett

Making a point that those who do not know Perl are forced to reinvent it (badly) - now that would be childish!
Martin Beckett

8
It is ridiculous to leave out the includes.
PascalVKooten

5

Using the lambda function to check the character is "_" then only count will be incremented else not a valid character

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
Please add an explanation - try not to post just plain blocks of code alone.
CertainPerformance

1
What do you think, that your answer offers, what a previous answer hasn't already covered? Please edit and expand your answer.
hellow

1
Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
Tim Diekmann

Used the lambda function to check the character is "_" then only count will be incremented else not a valid character.
Nagappa

[]( char c ){if(c =='_') return true; } invokes undefined behavior because you didn't return a value in all code paths
phuclv

4

There are several methods of std::string for searching, but find is probably what you're looking for. If you mean a C-style string, then the equivalent is strchr. However, in either case, you can also use a for loop and check each character—the loop is essentially what these two wrap up.

Once you know how to find the next character given a starting position, you continually advance your search (i.e. use a loop), counting as you go.


4

Count character occurrences in a string is easy:

#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 This is the same as the existing top answer from six years earlier – what was this meant to add? There is one difference: this answer uses the wrong header file. stdc++.h is specific to GCC, and even with that compiler it's only intended for use in precompiled headers.
Arthur Tacca


2

You can find out occurrence of '_' in source string by using string functions. find() function takes 2 arguments , first - string whose occurrences we want to find out and second argument takes starting position.While loop is use to find out occurrence till the end of source string.

example:

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

Bu şekilde yapardım:

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

Evet tabii ki, ve aslında bunu yaptım, ama idk, Visual Studio'dan SO formuna kopyaladığımda nasıl berbat olduğunu.
Shivam Jha

0

Böyle bir şey yapardım :)

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

-3

Deneyin

#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
Tüh! Yanlış dil.
Yörüngedeki Hafiflik Yarışları
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.