@alloooooo

Как решить задачу с символами? Почему не работает одна функция?

Добрый день/вечер. Я новичок и перешел к изучению темы с символами через getchar/putchar. Решал следующую задачу.
Ввести во входной поток последовательность символов, заканчивающуюся точкой (кодировка ASCII).
a) определить, сколько раз в этой последовательности встречается символ ‘a’;
b) определить, сколько символов ‘e’ предшествует первому вхождению символа ‘u’ ( либо сколько всего символов ‘e’ в этой последовательности, если она не содержит символа ‘u’ );
c) выяснить, есть ли в данной последовательности хотя бы одна пара символов-соседей ‘n’ и ‘o’, т.е. образующих сочетание ‘n’ ‘o’ либо ‘o’ ‘n’;
d) выяснить, чередуются ли в данной последовательности символы ‘+’ и ‘-‘, и сколько раз каждый из этих символов входит в эту последовательность;
e) выяснить, сколько раз в данную последовательность входит группа подряд идущих символов, образующих слово С++;
f) выяснить, есть ли среди символов этой последовательности символы, образующие слово char;
Каждое задание оформить в виде отдельной функции без параметров, возвращающей соответствующее заданию значение, т.е c прототипом, ввод описанной выше последовательности символов должен производиться в теле каждой создаваемой вами функции.
Меня интересует именно задание b. Дело в том, что различные входные данные проходят без проблем (например, eeeu, eeu. и т.д.), кроме одного - eeue. Введя эту последовательность, следующая за функцией kol_e, функция не предлагает мне ввести новую последовательность символов, а выводит сообщение о том, что пар - символов no или on нет.
Код этой функции:
int kol_e()
{
	int kol = 0, ch;
	cout << "Введите последовательность символов: ";
	while ((ch = getchar()) != '.')
		if (ch == 'u') break;
		else kol += (ch == 'e');

	return kol;
}

Пробовал как-нибудь по другому, например:
int kol_e()
{
	int ch,fl = 0, kol = 0;
	cout << "Введите последовательность символов: ";
	while (!fl && (ch = getchar()) != '.')
		if (ch != 'u') 
			kol += (ch == 'e');
		else ++fl;

	return kol;
}

но все равно не выходит.
Код всей задачи:
#include <stdio.h>
#include <iostream>
using namespace std;

int kol_a();
int kol_e();
int c_plus_plus();
void symb_char();
void on_no();
void plus_minus();

int main()
{
	setlocale(LC_ALL, "Russian");
	cout << "Количество символов а = " << kol_a() << endl;
	cout << "Количество символов e = " << kol_e() << endl;
	on_no();
	plus_minus();
	cout << "Количество С++ = " << c_plus_plus() << endl;
	symb_char();
	return 0;
}

int kol_a() // количество символов а
{
	int a, kol = 0;
	cout << "Введите последовательность символов: ";
	while ((a = getchar()) != '.')
		kol += (a == 'a');
	return kol;
}

int kol_e() // количество символов е до u, либо если u нет
{
	int kol = 0, ch;
	cout << "Введите последовательность символов: ";
	while ((ch = getchar()) != '.')
		if (ch == 'u') break;
		else kol += (ch == 'e');

	return kol;
}

void on_no() //последова-ти on или no
{
	int a = 0, b, fl = 0;
	cout << "Введите последовательность символов: ";
	while ((b = getchar()) != '.' && !fl)
	{
		switch (a) {
		case 'n': fl = (b == 'o'); break;
		case 'o': fl = (b == 'n'); break;
		}
		a = b;
	}
	cout << ((fl > 0) ? "Пара есть!" : "Пар нет!") << endl;
}

void plus_minus()
{
	int a = 0, b, fl = 0;
	int kol_p = 0, kol_m = 0;
	cout << "Введите последовательность символов: ";
	while ((b = getchar()) != '.')
	{
		fl += (a == '+' && b == '-');
		kol_p += (a == '+');
		kol_m += (b == '-');
		a = b;
	}
	if (fl > 0) 
		cout << "Символы + и - чередуются" << " ,количество + = " << kol_p << " количество - = " << kol_m << endl;
	else
		cout << "Символы + и - не чередуются" << " ,количество + = " << kol_p << " количество - = " << kol_m << endl;
}

int c_plus_plus() // кол-во С++
{
	int p,c = 0,d = 0, kol = 0;
	cout << "Введите последовательность символов: ";
	while ((p = getchar()) != '.')
	{
		kol += (c == 'C' && d == '+' && p == '+');
		c = d; d = p;
	}

	return kol;
}

void symb_char() // char
{
	int c = 0, h = 0, a = 0, r = 0;
	int k = 0;
	cout << "Введите последовательность символов: ";
	while ((r = getchar()) != '.')
	{
		k += (c == 'c' && h == 'h' && a == 'a' && r == 'r');
		c = h; h = a; a = r;
	}
	cout << ((k > 0) ? "YES" : "NO");
}

Подскажите, как можно решить проблему?
  • Вопрос задан
  • 64 просмотра
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Вам надо не делать break. А сохранить куда-то текущее значения счетчика kol и также установить флаг, что вы встретили u. После цикла, который заканчивается чтением точки, надо, если флаг u был не встречен, вернуть значение счетчика kol. Иначе - сохраненное значение.

Ваш первый вариант работал бы сразу, если бы вы сначала читали всю строчку в память и циклом по ней проходились. Но, поскольку надо всю строку всегда прочитать, то break ломает работу функции.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@lz961
В случае 'eeue' функция "kol_e" не обрабатывает введённую последовательность символов до конца, и её продолжает обрабатывать функция "on_no".
Ответ написан
@mayton2019
Bigdata Engineer
Размышления по code-review. Мне совершенно непонятно почему в одном условии выбран switch а в другом if.

switch (a) {
    case 'n': fl = (b == 'o'); break;
    case 'o': fl = (b == 'n'); break;
    }

Они ведь совершенно одинаковые по смыслу! Кроме того case без default секции всегда рассматривается как потенциальный баг.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы