Страница 1 из 1

С++. Контроль выхода за пределы массива.

Добавлено: 21 янв 2010, 12:48
Dragon
Есть отсортированная по алфавиту строка. Необходимо вывести буквы, которые есть в это строке (без повторов) и вывести кол-во их совпадений.

Алгоритм я вывел следующий:
- сравниваем первый элемент строки со вторым
- если они совпадают, то увеличиваем счетчик на 1, если нет, то прерываем цикл и выводим на печать первый элемент и значение счетчика.
- если индекс первого элемента > 0 и значение первого элемента == значению предыдущего элемента (совпадение учитывалось на предыдущей итерации), то прерываем цикл, НЕ увеличиваем счетчик и НЕ выводим ничего на печать.

Собственно все вроде как подсчитывает, но последний символ не хочет выводить т.к. внутренний цикл доходит до границы массива и прекращается, а внешний цикл отказывется в связи с этим что-либо выводить или выводит не точные данные, хотя должен по алгоритму работать.

Код:

Код: Выделить всё

//s - строка с упорядоченным по алфавиту текстом
int index1, index2, counter = 1;
bool noprint = false;

    for(index1 = 0; index1 < s.length(); index1++)
    {//сравниваем левый символ с правым
        for(index2 = index1 + 1; index2 < s.length(); index2++)
        {
            if(index1 > 0 && (s[index1] == s[index1-1]))
            {//если значение следующего элемента идентичено предыдущему, то повтор учтен
                noprint = true; //на экран ничего не выводим
                break;
            }

            if(s[index1] == s[index2])
            {//если левый элемент равен правому, увеличиваем счетчик
                counter++;
            }
            else
            {//иначе нет смысла сверять строку далее
                noprint = false; //разрешить вывод данных
                break;
            }
        }

        if(!noprint)
        {//если вывод разрешен
            cout << s[index1] << " - " << counter << endl; //выводим значение левого элемента
            counter = 1; //сбрасываем счетчик
        }
    }
Примеры работы:
Input: aaa
Output: a - 3

Input: aaab
Output: a - 3

Input: aaabbc
Output: a - 3, b - 2

Input: aaabccd
Output: a - 3, b - 1, c - 2

Input: abb
Output: a - 1, b -2, b - 1
Что я упустил, делаю неверно?

Re: С++. Контроль выхода за пределы массива.

Добавлено: 21 янв 2010, 13:21
BulldozerBSG
Зачем так гемороиться. А не проще создать массив интов размером 256 элементов и инициализировать его нулями. Пройтись по строке. И соответствующую букве ячейку массива увеличить на 1. А далее пройтись по массиву и там где содержимое больше нуля вывести информацию по букве и количеству совпадений.

Re: С++. Контроль выхода за пределы массива.

Добавлено: 21 янв 2010, 13:57
Dragon
Не совсем понял.
Считывать строку символов. Пока есть совпадения увеличиваеть первый элемент массива на 1. Совпадения закончились, начинаем увеличиваеть следующую ячейку и так до конца строки. Затем взять первый символ строки и сверять его с другими символами. Закончил повторяться, вывели на экран символ и первый элемент массива int. Затем переходим к следующему символу и элементу массива int.

Если так, то по-моему по геморойности не отличается :)

Re: С++. Контроль выхода за пределы массива.

Добавлено: 21 янв 2010, 14:27
BulldozerBSG
Нет, не так. Приведенный код все объяснит. В нем выводится не сколько раз встретился символ, а сколько раз повторился. Если надо другое то просто уберешь -1 при печати.

Код: Выделить всё

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void main()
{
	char s[] = "aaabbsadfbb";
	char m[256];
	memset(m, 0, sizeof(m));
	for (int i = 0; i < strlen(s); i++)
	{
		m[s[i]]++;
	}
	for (int i = 0; i < sizeof(m); i++)
	{
		if (m[i] > 0)
		{
			printf("Symvol: %c; Povtorenij: %d\n", (char) i, m[i] - 1);
		}
	}
}