Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.03.2013, 00:04   #1
Elnamir
Пользователь
 
Регистрация: 21.03.2013
Сообщений: 13
По умолчанию Повторение слова

Всем привет
Написал алгоритм для вычисления повторения слов в строке. Но происходит переполнение. Не могли бы вы меня направить в правильном направление?
Код должен быть строго по стандартам ANSI C

Код:
#include <stdio.h>
#include <cstring>
#include <iostream>
const int MAX_WORDS = 100;
const int MAX_SIMBOLS = 256;
const int MAX_SIMBOLS_IN_WORDS = 30;
struct word
{
	char s[MAX_SIMBOLS_IN_WORDS];
	int count;
};

int main(void)
{
	setlocale(LC_ALL,"Russian");
	char str[MAX_SIMBOLS];
	word arr[MAX_WORDS];
	printf("Введите строку в которой не более %d символов:", MAX_SIMBOLS);
	gets(str);
	for(int i = 0, p = 0; str[i] != '\0'; i++){
		char str2[MAX_SIMBOLS_IN_WORDS];
		if((str[i] != ' ') ){
			str2[i] = str[i];
		}
		else if((str[i] == ' ') || (str[i+1] == '\0')){
			int t = 0;
			for(int j = 0; j <= MAX_WORDS; j++){
				if(strcmp(arr[j].s,str2) == 0){
					arr[j].count++;
					t = 1;
				}
			}

			if(t != 1){
				strcpy(arr[p].s,str2);
				arr[p].count = 0;
				p++;
			}
		}
	}
return 0;
}
И еще можете подсказать что нибудь по оптимизации

Последний раз редактировалось Elnamir; 21.03.2013 в 00:52.
Elnamir вне форума Ответить с цитированием
Старый 21.03.2013, 01:03   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_SYMBOLS_IN_WORD 30

typedef struct _word
{
    char s[MAX_SYMBOLS_IN_WORD];
    int count;
} word;

struct _list
{
    word w;
    struct _list *next;
};

typedef struct _list list;

int main(void)
{
    list *head = NULL;
    //system("chcp 1251 > nul");
    printf("Введите строку:\n");
    char str[MAX_SYMBOLS_IN_WORD];
    while (scanf("%s", str)) {
        if (!strcmp(str, "exit")) {//"костыль" для выхода из цикла - если встретится слово exit, то завершаем ввод
            break;
        }
        list *tmp = head, *last = head;
        while (tmp && strcmp(str, tmp->w.s)) {
            last = tmp;
            tmp = tmp->next;
        }
        if (tmp) {
            tmp->w.count++;
        } else {
            tmp = calloc(1, sizeof(*tmp));
            strcpy(tmp->w.s, str);
            tmp->w.count = 1;
            tmp->next = NULL;
            if (last) {
                last->next = tmp;
            } else {
                head = tmp;
            }
        }
    }
    list *tmp = head;
    while (tmp) {
        printf("%s %d\n", tmp->w.s, tmp->w.count);
        tmp = tmp->next;
    }
    while (head) {
        tmp = head;
        head = head->next;
        free(tmp);
    }
    return 0;
}
Замечания:
1) for(int j = 0; j <= MAX_WORDS; j++){ - выход за пределы массива
2) <cstring>, <iostream> - это С++, а не Си
3) Переписал так, потому что есть "неприятная" ошибка, связанная с тем, что str2 перед сравнением нужно завершать \0, чтобы strcmp "не лез" в память, не принадлежащую строке (поэтому мне было легче переписать логику, чем исправлять эту ошибку)
И пока присутствуют ошибки в формировании str2 (не так идут индексы) - поэтому легче переложить эту работу на компьютер, переписав считывание

И вообще, что за ограничители в 100 слов
Только динамическая память, только хардкор
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 21.03.2013 в 01:18.
BDA вне форума Ответить с цитированием
Старый 21.03.2013, 01:09   #3
Elnamir
Пользователь
 
Регистрация: 21.03.2013
Сообщений: 13
По умолчанию

Спасибо, конечно
А можно ли все это реализовать без указателей ?
Или указать где у меня ошибка
Elnamir вне форума Ответить с цитированием
Старый 21.03.2013, 01:24   #4
Elnamir
Пользователь
 
Регистрация: 21.03.2013
Сообщений: 13
По умолчанию

Большое спасибо за помощь, разобрался. Действительно с динамической памятью легче работать. Просто хотелось все это реализовать статически. Но увы
Elnamir вне форума Ответить с цитированием
Старый 21.03.2013, 01:27   #5
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Без указателей:
Код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_WORDS 100
#define MAX_SYMBOLS_IN_WORD 30

typedef struct _word
{
    char s[MAX_SYMBOLS_IN_WORD];
    int count;
} word;

int main(void)
{
    system("chcp 1251 > nul");
    printf("Введите строку:\n");
    word arr[MAX_WORDS];
    char str[MAX_SYMBOLS_IN_WORD];
    int word_count = 0;
    while (scanf("%s", str)) {
        if (!strcmp(str, "exit")) {
            break;
        }
        int i = 0;
        while (i < word_count && strcmp(str, arr[i].s)) {
            ++i;
        }
        if (i == word_count) {
            if (word_count == MAX_WORDS) {
                printf("Переполнение массива слов\n");
                break;
            }
            strcpy(arr[i].s, str);
            arr[word_count++].count = 1;
        } else {
            arr[i].count++;
        }
    }
    int i;
    for (i = 0; i < word_count; ++i) {
        printf("%s %d\n", arr[i].s, arr[i].count);
    }
    return 0;
}
Пожалуйста.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 21.03.2013, 02:05   #6
Elnamir
Пользователь
 
Регистрация: 21.03.2013
Сообщений: 13
По умолчанию

Спасибо, что помогли реализовать без указателей. А не могли вы пояснить, что происходит в данной строке while (i < word_count && strcmp(str, arr[i].s)). Само выражение
Elnamir вне форума Ответить с цитированием
Старый 21.03.2013, 02:10   #7
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

word_count - количество уже запомненных слов.
Перебираем все слова от 0 до word_count - 1 (т.е. i < word_count).
Сравниваем считанное слово с i-м словом из массива.
Выражение будет 0 (выход из цикла) или если в массиве нету больше слов, или если текущее и считанное слово совпали.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Повторение процедуры Firebird Общие вопросы Delphi 6 23.11.2012 12:03
Вывести слова предложения в таком порядке, чтобы последняя буква каждого слова совпадала с первой буквой следующего слова ( java ) huhu Помощь студентам 0 06.04.2012 19:42
Повторение команд Mihanches Общие вопросы Delphi 5 07.10.2010 14:12
Повторение CraftR14 Общие вопросы Delphi 8 17.04.2010 20:15