0 / 0 / 0
Регистрация: 28.03.2015
Сообщений: 11
1

Напечатать все слова, которые встречаются в последовательности более одного раза

19.04.2015, 21:41. Показов 1867. Ответов 12
Метки нет (Все метки)

Дана последовательность, содержащая от 1 до 30 слов, в каждом из которых от 1 до 5 строчных русских букв; между соседними словами - запятая, за последним словом - точка. Напечатать все слова, которые встречаются в последовательности более одного раза.
После чтения строки выходит ошибка: необработанное исключение по адресу 0x0FEEF950 (msvcr110d.dll) в Часть 2 - Программа 1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCCCCCCCC.
Помогите, пожалуйста, исправить код.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <locale.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
 
#define ZNAKI ",."
#define SLOVA 30
#define SIMVOL 180
void main (void) 
{
    
        int i, j, c = 0, m = 0, n = 0, flag;
        char str[SIMVOL], *ptr = 0, *word[SLOVA], *povt[SLOVA];
 
        SetConsoleCP(1251);
        SetConsoleOutputCP(1251);
 
        printf ("Дана последовательность, содержащая от 1 до 30 слов, в каждом из которых от 1 до 5 строчных русских букв; между соседними словами - запятая, за последним словом - точка. Напечатать все слова, которые встречаются в последовательности более одного раза.\n\n");
        printf ("Введите строку: \n");
        fgets (str, 180, stdin);
        printf ("Ваша введенная строка: \n");
        fputs (str, stdout);
 
        for (ptr = strtok (str, ZNAKI); ptr != 0 && c < SLOVA; c++, ptr = strtok (0, ZNAKI))
            word[c] = ptr;
        
        fputs (*word, stdout);
        for (i = 0; i < c; i++)
        {
            flag = 0;
            for (j = 0; j < c; j++)
            {
                if (i == j)
                {
                    flag = 1;
                    break;
                }
                if (flag == 0)
                {
                    if (strcmp (word[i], word[j]) == 0)
                    {
                        for (m = 0; m < SLOVA; m++)
                        {
                            if (strcmp (povt[m], word[i]) == 0)
                            {
                                flag = 1;
                                break;
                            }
                            else 
                            {
                                povt[n] = word[i];
                                n++;
                            }
                        }
                    }
                }
            }
        }
        fputs (*povt, stdout);
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.04.2015, 21:41
Ответы с готовыми решениями:

Напечатать символы, которые встречаются в заданной последовательности более одного раза
Пусть задана произвольная последовательность символов. Признак конца последовательности – точка....

Найти и напечатать числа, которые встречаются в массиве более одного раза
Одномерный массив А состоит из 30 элементов. Найти и напечатать числа, которые встречаются в...

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

Напечатать все слова, которые встречаются в последовательности по одному разу
Вообщем дана строка в файле,задача Напечатать все слова, которые встречаются в последовательности...

12
201 / 199 / 65
Регистрация: 06.10.2013
Сообщений: 552
19.04.2015, 22:09 2
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
strcmp (word[i], word[j]) == 0
Если я правильно понимаю логику хранения слов в оригинальном буфере, то это сравнение может быть некорректным, т.к. эта функция проверяет строку до '\00'.
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
ptr = strtok (str, ZNAKI)
1е слово не пропускается случаем?
0
0 / 0 / 0
Регистрация: 28.03.2015
Сообщений: 11
19.04.2015, 22:35  [ТС] 3
В
Цитата Сообщение от XZentus Посмотреть сообщение
Если я правильно понимаю логику хранения слов в оригинальном буфере, то это сравнение может быть некорректным, т.к. эта функция проверяет строку до '\00'.
По-моему эта проверка корректна, т.к. результат возвращаемый функцией strcmp может быть нуль или меньше или больше нуля

Добавлено через 2 минуты
Цитата Сообщение от XZentus Посмотреть сообщение
1е слово не пропускается случаем?
Здесь проверка должна начинаться с самого начала строки str. Думаю проблема не в этом.
0
201 / 199 / 65
Регистрация: 06.10.2013
Сообщений: 552
19.04.2015, 22:38 4
Строка: "123,1234,456,123,234"
1 слово повторяется - 123.
Но strcmp проверять будет подстроки "123,1234,456,123,234" и "123,234" которые между собой не равны.

Добавлено через 2 минуты
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
Здесь должно начинаться с самого начала, строки str.
Тогда почему не ptr = str ?
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
Думаю проблема не в этом.
Не в этом, но я написал про те подозрительные места, которые бросились в глаза.
0
0 / 0 / 0
Регистрация: 28.03.2015
Сообщений: 11
19.04.2015, 22:44  [ТС] 5
Цитата Сообщение от XZentus Посмотреть сообщение
Тогда почему не ptr = str ?
А зачем в ptr присваивать всю строку str? ptr только для того, чтобы туда записать слово, которое находится до запятой.
0
201 / 199 / 65
Регистрация: 06.10.2013
Сообщений: 552
19.04.2015, 22:47 6
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
чтобы туда записать слово, которое находится до запятой.
Именно. Или его не надо обрабатывать?

Добавлено через 1 минуту
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
fputs (*word, stdout);
*word - некорректное разыменование. Скорее всего, из-за него падает.
0
0 / 0 / 0
Регистрация: 28.03.2015
Сообщений: 11
19.04.2015, 22:54  [ТС] 7
Цитата Сообщение от XZentus Посмотреть сообщение
Строка: "123,1234,456,123,234"
1 слово повторяется - 123.
Но strcmp проверять будет подстроки "123,1234,456,123,234" и "123,234" которые между собой не равны.
А почему так? Разве не будут сравниваться две строки word[i] и word[j], где i и j - номера строк в массиве word?

Добавлено через 1 минуту
Цитата Сообщение от XZentus Посмотреть сообщение
Именно. Или его не надо обрабатывать?
Это слово сразу же записывается в массив:
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
word[c] = ptr;
Добавлено через 3 минуты
Цитата Сообщение от XZentus Посмотреть сообщение
Сообщение от GROOVE1995
fputs (*word, stdout);
*word - некорректное разыменование. Скорее всего, из-за него падает.
Без этой строки все равно не работает код.
0
201 / 199 / 65
Регистрация: 06.10.2013
Сообщений: 552
19.04.2015, 22:54 8
Не-а.
*char - это указатель на адрес, не более того. Си не хранит никакой информации о длине строки, поэтому её конец - это ближайший нулевой байт.
Запись word[c] = ptr; означает: "поместить в ячейку памяти *(word+c) адрес ptr." Больше ничего эта команда не делает.
0
0 / 0 / 0
Регистрация: 28.03.2015
Сообщений: 11
19.04.2015, 22:56  [ТС] 9
А как правильно присвоить тогда?
0
201 / 199 / 65
Регистрация: 06.10.2013
Сообщений: 552
19.04.2015, 23:12 10
Проще всего написать свой аналог strcmp для этой задачи, если не хочется делать рефакторинг.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
11658 / 7171 / 1704
Регистрация: 25.07.2009
Сообщений: 13,142
20.04.2015, 00:14 11
Не заморачиваясь русскими буквами и прочими запятыми с точками
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
 
typedef struct COUNTERSTREE {
    const char * word;
    size_t count;
    struct COUNTERSTREE * left;
    struct COUNTERSTREE * right;
} counterstree_t;
 
int push(counterstree_t ** root, const char * word) {
    if ( ! *root ) {
        counterstree_t * node = malloc(sizeof(counterstree_t));
        if ( ! node )
            return -1;
        
        node->word = word;
        node->count = 1;
        node->left = NULL;
        node->right = NULL;
        
        *root = node;
        return 0;
    }
    else {
        int dif = strcmp((*root)->word, word);
        if ( dif > 0 )
            return push(&((*root)->left), word);
        else if ( dif < 0 )
            return push(&((*root)->right), word);
        else {
            (*root)->count += 1;
            return 0;
        }
    }
}
 
void del(counterstree_t ** root) {
    if ( *root ) {
        del(&((*root)->left));
        del(&((*root)->right));
        free(*root);
        *root = NULL;
    }
}
 
void print_if(counterstree_t * root, int (*test)(counterstree_t*)) {
    if ( root ) {
        print_if(root->left, test);
        if ( test(root) )
            printf("%s\n", root->word);
        print_if(root->right, test);
    }
}
 
int more1(counterstree_t * node) {
    return ( node->count > 1 );
}
 
#define DELIM " \t\n"
 
int main(void) {
    char buf[BUFSIZ];
    
    while ( printf("String: ") && fgets(buf, BUFSIZ, stdin) && *buf != '\n' ) {
        counterstree_t * tree = NULL;
        char * ptr = strtok(buf, DELIM);
        
        while ( ptr ) {
            if ( push(&tree, ptr) ) {
                fprintf(stderr, "Memory error!\n");
                return 1;
            }
            ptr = strtok(NULL, DELIM);
        }
        
        print_if(tree, more1);
        del(&tree);
    }
    
    return 0;
}
0
0 / 0 / 0
Регистрация: 28.03.2015
Сообщений: 11
20.04.2015, 00:47  [ТС] 12
Спасибо, но мне нужен код на Си,а не на С++.

Добавлено через 1 минуту
Получился рабочий код, но есть проблема: слова в выводе дублируются из-за наложения индексов в цикле for. Подскажите пожалуйста, как исправить.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <locale.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
 
#define S 256
#define W 30
#define Z ",."
void main (void) 
{
    int i, j, c = 0, m, n = 0, f;
    char str[S], *ptr = 0, *word[W] = {0}, *povt[W] = {0};
    do
    {
        SetConsoleCP(1251);
        SetConsoleOutputCP(1251);
 
        printf ("Дана последовательность, содержащая от 1 до 30 слов, в каждом из которых от 1 до 5 строчных русских букв; между соседними словами - запятая, за последним словом - точка. Напечатать все слова, которые встречаются в последовательности более одного раза.\n\n");
        printf ("Введите строку:\n");
        if (scanf("%255[^\n]", str) == 1 && fgetc(stdin) == '\n')
        {
            for (ptr = strtok(str,Z); ptr != 0 && c < W; c++, ptr = strtok(0,Z))
                word[c] = ptr;
            printf ("Cлова:\n");
            for (i = 0; i < c; i++)
                printf ("%s\n", word[i]);
            printf ("\n");
            printf ("Повторяющиеся слова:\n");
            for (i = 0; i < c; i++)
            {
                for (j = 0; j < c; j++)
                {
                    if (i != j && strcmp(word[i], word[j]) == 0)
                        printf("%s\n", word[i]);
                }
            }
        }
        
    }           
    while (getch() != 27);
}
Добавлено через 7 минут
Получился рабочий код, но есть проблема: слова в выводе дублируются из-за наложения индексов в цикле for. Подскажите пожалуйста, как исправить.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <locale.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
 
#define S 256
#define W 30
#define Z ",."
void main (void) 
{
    int i, j, m;
    char str[S], *ptr = 0, *word[W] = {0}, *povt[W] = {0};
    do
    {
        SetConsoleCP(1251);
        SetConsoleOutputCP(1251);
 
        printf ("Дана последовательность, содержащая от 1 до 30 слов, в каждом из которых от 1 до 5 строчных русских букв; между соседними словами - запятая, за последним словом - точка. Напечатать все слова, которые встречаются в последовательности более одного раза.\n\n");
        printf ("Введите строку:\n");
        if (scanf("%255[^\n]", str) == 1 && fgetc(stdin) == '\n')
        {
            for (ptr = strtok(str,Z); ptr != 0 && m < W; m++, ptr = strtok(0,Z))
                word[m] = ptr;
            printf ("Cлова:\n");
            for (i = 0; i < m; i++)
                printf ("%s\n", word[i]);
            printf ("\n");
            printf ("Повторяющиеся слова:\n");
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < m; j++)
                {
                    if (i != j && strcmp(word[i], word[j]) == 0)
                        printf("%s\n", word[i]);
                }
            }
        }
        
    }           
    while (getch() != 27);
}
0
201 / 199 / 65
Регистрация: 06.10.2013
Сообщений: 552
20.04.2015, 20:23 13
Цитата Сообщение от GROOVE1995 Посмотреть сообщение
Спасибо, но мне нужен код на Си,а не на С++.
А где ты у easybudda там плюсы увидел?

Цитата Сообщение от GROOVE1995 Посмотреть сообщение
слова в выводе дублируются из-за наложения индексов в цикле for.
C
1
2
3
4
5
6
7
8
for (j = 0; j < m; j++)
 {
    if (i != j && word[j] != 0 && word[i] != 0 && strcmp(word[i], word[j]) == 0)
    {
        printf("%s\n", word[i]);
        word[j] = NULL;
    }
}
Грязный хак, сам не тестил. Но, возможно, сработает.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.04.2015, 20:23
Помогаю со студенческими работами здесь

Напечатать все слова, которые встречаются в последовательности по одному разу
Сам попробовал написать код,но везде одни ошибки. #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt;...

Напечатать все слова, которые встречаются в последовательности более одного раза
Дана последовательность, состоящая от 1 до 30 слов в каждом из которых от 1 до 5 малых латинских...

Напечатать все элементы, которые встречаются более одного раза
ЗАДАЧА 5. Выполнить действия над массивами. В таблице при формулировании задания для разъяснения...

Исключить из файла все слова, которые встречаются более одного раза
Найти в файле f все слова которые встречаются более одного раза исключить их с файла f и получить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru