Задать вопрос
@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");
}

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

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

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

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

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

Похожие вопросы