Підрахунок подій символів у рядку в 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.