Підрахунок подій символів у рядку в C ++


199

Як я можу порахувати кількість "_"рядків типу "bla_bla_blabla_bla"?


17
@jdmichal: "погано задане питання для початківців"! = "домашнє завдання"

@Roger: Звичайно, це, можливо, не домашнє завдання, але добре припустити його домашнє завдання хоча б для відповідей, тому що 1) зіпсувати питання домашнього завдання погано для навчання, 2) ти все ще можеш навчитися з хороших "відповідей на домашнє завдання", 3 ) ОП може (і має) дати відгук і сказати, що це не домашнє завдання
шнадер

3
@schnaader: Що робити, якщо ОП каже, що це не їх домашнє завдання, чи не все одно це буде домашнє завдання для когось іншого? Чи повинні ми їм «зіпсувати» це? І навпаки: хтось, хто не знає C ++, але вже поза школою, може задати це питання; ти б дав їм "повну" відповідь? Чому характеристика плаката - присвоєння цього вчителем (домашнє завдання) - є категоризацією змісту питання (теги)? Схоже, всі відповіді нижче, включаючи і ваші, і мої, були б однаковими незалежно від цього тегу.

@Roger: Я б справді дав ще одну відповідь, якби був впевнений, що це не домашнє завдання. У цьому випадку я відповів повним кодом С замість псевдокоду. І псування інших людей не так важливо - якщо вони можуть шукати його тут, вони можуть шукати і в Google. Також пошук чогось насправді може бути набагато кращим (хоча і не найкращим) способом навчитися, ніж просто опублікувати домашнє завдання та отримати повний код / ​​рішення через кілька хвилин.
шнадер

2
@schnaader: Там є 32 відповіді, і порядок сортування змінюється, який? Як ви вважаєте, я не мав би дати відповідь "повного коду" на це питання "домашнє завдання" ? Якщо бути абсолютно чесним, то тут питання корисно заохочувати думати незалежно від того, чи це домашнє завдання, і мені подобається, що ваша відповідь набагато краще, ніж якщо б у неї був повний код С, з цієї причини. Ви корисні, відповідаючи на запитання, а не на сторонні наміри плаката.

Відповіді:


418
#include <algorithm>

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

15
Третій аргумент - це тип char, тобто одинарна цитата, а не подвійна цитата ...
Emerson Xu

1
Це найкраща відповідь.
Кончог

Маленька примітка, але тип повернення зазвичай підписаний. Чомусь std::countтип повернення iterator_traits<InputIt>::difference_type, який для більшості стандартних контейнерів є std::ptrdiff_t, ні std::size_t.
Даніель Стівенс

30

Псевдокод:

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

EDIT: Приклад 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 Я насправді про це думав. На жаль, мого розуміння функціонального програмування на C ++ практично немає.
jdmichal

8
Я думаю, що дзвонити в веб-сервіс було б набагато веселіше, ніж лямбда, тоді основний алгоритм не просто непереборний, він зберігається в іншому місці.
Ben Voigt

Це не домашнє завдання. Я новачок у програмі c ++ і не маю достатньої кількості знань c ++, щоб програмувати це вдосконалено. Читайте: якомога менше. Я в змозі запрограмувати це просто, за допомогою циклу for і т.д., але я шукав складне рішення, щось на зразок рішення Дієго. Наступного разу я дам більше інформації для причини питання.
andre de boer

Крім того, ви хочете споживати суміжні події, якщо ви не хочете дублікатів. Як, наприклад, підраховуючи, скільки штук ви отримаєте після розбиття рядка на потрібний символ.
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. Тож ОП: Вибачаюсь і сподіваюся, що ви правильно виконали домашнє завдання, незважаючи на те, що я розмовляв, і такі відповіді, як моя, не відштовхували вас від участі на сайті.


1
Серйозно? Цілеспрямовано розгублена відповідь - це найкраще, що ти можеш зробити, і ти вважаєш, що це колись було б доречним?

4
@Tamas: int (true) завжди 1 у C ++.

6
справді старомодне рішення оголосить прототип для sprintf замість #include цілого файлу заголовка !
John Dibling

5
@Tamas: Звичайно, ні, але мені не весело, коли я відповідаю на запитання початківців.

11
Любіть це. Сором, це порушує правило подвійного підкреслення.
Мартін Йорк

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

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

10

Ви називаєте це ... версія лямбда ...

using namespace boost::lambda;

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

Вам потрібно кілька включень ... Я залишаю це як вправу ...


7
Ви справді думаєте, що новачок збирається зрозуміти щось із цього?
Джош Стодола

2
@Josh: У деяких коментарях це, мабуть, є наслідком дитячого сміху .

5
Деякі з найкращих світових програмістів витратили останні 15 років, що розвиваються на C ++, до того, як ми можемо це написати - це не по-дитячому!
Мартін Бекетт

Звертаючи увагу на те, що ті, хто не знає Perl, змушені його винаходити (погано) - тепер це було б по-дитячому!
Мартін Бекетт

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
Будь ласка, додайте пояснення - намагайтеся не публікувати лише прості блоки коду.
Окреме виконання

1
Як ви думаєте, що пропонує ваша відповідь, що попередня відповідь ще не висвітлена? Відредагуйте та розгорніть свою відповідь.
привіт

1
Дякуємо за цей фрагмент коду, який може надати деяку обмежену, негайну допомогу. Належне пояснення було б значно поліпшити свою довгострокову цінність , показуючи , чому це хороше рішення проблеми, і зробить його більш корисним для читачів майбутніх з іншими подібними питаннями. Будь ласка, відредагуйте свою відповідь, щоб додати пояснення, включаючи зроблені вами припущення.
Тім Дікманн

Використовувана функція лямбда для перевірки символу "_", тоді буде нарощено лише кількість, але не дійсний символ.
Нагаппа

[]( char c ){if(c =='_') return true; }посилається на невизначену поведінку, оскільки ви не повернули значення у всіх кодових шляхах
phuclv

4

Існує кілька методів std :: string для пошуку, але знайти, мабуть, те, що ви шукаєте. Якщо ви маєте на увазі рядок у стилі C, то еквівалент strchr. Однак у будь-якому випадку ви також можете скористатися циклом для перевірки кожного символу - цикл - це по суті те, що ці два загортають.

Як тільки ви знаєте, як знайти наступного символу, який задається початковою позицією, ви постійно просуваєте пошук (тобто використовуєте цикл), рахуючи під час проходження.


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, і навіть з цим компілятором він призначений лише для використання у попередньо складених заголовках.
Артур Такка


2

Ви можете дізнатись появу '_' у вихідному рядку, скориставшись функціями string. 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
Ого! Неправильна мова.
Гонки легкості по орбіті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.