Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
1 / 1 / 0
Регистрация: 22.10.2013
Сообщений: 17
1

Вывести слова строки в порядке убывания числа букв в них

25.10.2013, 18:50. Показов 2398. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Собственно, имеется готовая на половину программа:

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "stdio.h"
#include "conio.h"
#include "math.h"
#include "string.h"
#include "stdafx.h"
#include <iostream>
 
 
struct word  //пользовательский тип с атрибутами слова в строке - координаты начала и конца и длина
{
    int b,e,l;
};
 
float dist(float a[],int i,int r) //функция вычисления расстояния
{
    float dst=0;
    int end=r;
    
    for(int j=0;j<end ;j++)
        dst+=fabs(a[i]-a[j]);
    return dst;
}
 
 
int _tmain(int argc, _TCHAR* argv[]) 
{
    
    float* a;    //объявление указателя на float
    int n;       //его размер
    float minr=0;  //минимум расстояния
    int minc=0;    //индекс самого близкого к соседям элемента
 
    char st[359];   //исходная строка
    int k=1;          //число слов в строке,изначсально с учетом последнего слова
    int* wrds;      //указатель на int
    word* arw;      //указатель на пользовательский тип
//Задание 1. Поиск элемента с наименьшим расстоянием до других
    printf("Enter number of array elms: ");  //приглашение на ввод количества элементов массива
    scanf_s("%d",  &n);
    printf("\n");                            //считывание с клавиатуры количества элементов
    a = new float[n];                        //динамическое выделение  памяти для массива n элементов
    printf("Fill your array\n");             //заполнение массива
    for(int i=0;i<n;i++)
        scanf_s("%f", &a[i]);
 
    int p=0;
    for(int i=0;i<n;i++)
        if(dist(a,i,n)<dist(a,p,n))
 
        {
            minr=dist(a,i,n);
            minc=i;
            p=i;
        }
 
    printf("The element # %d has the least distance. The distance is %5.2f\n", minc, minr);
    delete a;  //удаление массива
 
//Задание 2. Вывод слов строки по увеличению количества букв
    printf("Enter your string: ");             //приглашение на ввод строки
    scanf_s("%s",st);                          //считывание с клавиатуры строки
    printf("\n");
 
    while(strlen(st)>200)                      //защита от дураков
    {
        printf(" You have broken my program \n that was awfully nice of you,try again \n");
        scanf_s("%s",st);
    }
 
        
 
    for(unsigned int i=0;i<strlen(st);i++)       //узнаем число слов
        if (st[i]==' ') k++;
 
    wrds = new int[k];                           //формируем массив, элементы которого - координаты пробелов
    int j=0;
    for(int i=0;i<k;i++)
        if (st[i]==' ')
        {
            wrds[j]=i;
            j++;        
        }
 
    arw = new word[k];    //массив структур с атрибутами слов
 
    arw[0].b=0;           //заполняем  массив, 1й и последнийй элементы отдельно, остальные в цикле
    arw[0].e=wrds[0]-1;
    arw[0].l=wrds[0]-1;
 
    arw[k-1].b=0;
    arw[k-1].e=strlen(st);
    arw[k-1].l=wrds[0]-1;
 
    for(int i=1;i<k-1;i++)
    {
        arw[i].b=wrds[i]+1;
        arw[i].e=wrds[i+1]-1;
        arw[i].l=arw[i].e-arw[i].b;
    }
    
 
    word buf={0,0,0};      //сортируем массив по убыванию длины слова
    for(int i=0;i<k-1;i++)
        for( int j=i+1;j<k;j++)
            if(arw[i].l<arw[j].l)
            {
                buf.b=arw[i].b;
                buf.e=arw[i].e;
                buf.l=arw[i].l;
 
                arw[i].b=arw[j].b;
                arw[i].e=arw[j].e;
                arw[i].l=arw[j].l;
 
                arw[j].l=buf.b;
                arw[j].l=buf.b;
                arw[j].l=buf.b;
            }
 
    printf("Words sorted by decreasing order: \n");  //вывод слов строки по убыванию длины
    for(int i=0;i<k;i++)
    {
        for(int j=arw[i].b;j<arw[i].e;j++)
            printf("%ch", st[j]);
        printf("\n");
    }
 
    delete wrds;
    delete arw;
    std::cin.getch();
    return 0;
 
}
Проблема заключается в том, что вторая половина программы, отвечающая за вывод слов строки, работает некорректно, а точнее не работает вовсе. Никак не могу найти, где же я все-таки нагрешил.
Помогите пожалуйста.

Добавлено через 1 час 17 минут
Что ж так пусто то тут?

Добавлено через 34 минуты
Забыл сказать, что при запуске программы после работы с первой частью программы, верно выводится приглашение на ввод строки, после чего сразу заключительная фраза и программа завершается
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2013, 18:50
Ответы с готовыми решениями:

Строки. Вывести слова в порядке убывания количества цифр в них
вводится предл.(слова разделены пробелами в конце точка).внутри слов встречаются цифры.вывести...

Cлова строки расположить в порядке убывания в них букв
Вообще дуб-дубом как это сформировывать... Можно хотя бы набросок, пожалуйста) Строка содержит...

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

Вывести слова строки в порядке убывания длины
требуется написать программу которая: -считает количество слов в предложении -выводит слова...

5
27 / 27 / 6
Регистрация: 27.09.2009
Сообщений: 101
25.10.2013, 20:06 2
Я бы читал строку с помощью gets, так как вроде scanf считает до первого разделителя(пробел тоже разделитель). И у вас в 77 строке цикл до k, но там ведь вы по логике должны пробегать по всей строке(ища координаты пробелов), а получается только по найденному количеству пробелов, что не соответствует длине строки. Так же надо учитывать, что можно ввести несколько пробелов и учитывать,что после последнего слова будет пробел ну и т.д.
1
1 / 1 / 0
Регистрация: 22.10.2013
Сообщений: 17
25.10.2013, 21:16  [ТС] 3
[QUOTE=Vivo;5236273]Я бы читал строку с помощью gets, так как вроде scanf считает до первого разделителя(пробел тоже разделитель)

если интересно, то я раскопал, что это можно делать и с помощью scanf в таком виде:
C++
1
scanf("%359s\n", st);
gets же считается самой опасной на свете командой

Добавлено через 31 минуту
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "stdio.h"
#include "conio.h"
#include "math.h"
#include "string.h"
#include "stdafx.h"
#include <iostream>
 
 
struct word  //пользовательский тип с атрибутами слова в строке - координаты начала и конца и длина
{
    int b,e,l;
};
 
float dist(float a[],int i,int r) //функция вычисления расстояния
{
    float dst=0;
    int end=r;
    
    for(int j=0;j<end ;j++)
        dst+=fabs(a[i]-a[j]);
    return dst;
}
 
 
int _tmain(int argc, _TCHAR* argv[]) 
{
    
    float* a;    //объявление указателя на float
    int n;       //его размер
    float minr=0;  //минимум расстояния
    int minc=0;    //индекс самого близкого к соседям элемента
 
    char st[359];   //исходная строка
    int k=1;          //число слов в строке,изначсально с учетом последнего слова
    int* wrds;      //указатель на int
    word* arw;      //указатель на пользовательский тип
//Задание 1. Поиск элемента с наименьшим расстоянием до других
    printf("Enter number of array elms: ");  //приглашение на ввод количества элементов массива
    scanf_s("%d",  &n);
    printf("\n");                            //считывание с клавиатуры количества элементов
    a = new float[n];                        //динамическое выделение  памяти для массива n элементов
    printf("Fill your array\n");             //заполнение массива
    for(int i=0;i<n;i++)
        scanf_s("%f", &a[i]);
 
    int p=0;
    for(int i=0;i<n;i++)
        if(dist(a,i,n)<dist(a,p,n))
        {
            minr=dist(a,i,n);
            minc=i;
            p=i;
        }
 
    printf("The element # %d has the least distance. The distance is %5.2f\n", minc, minr);
    delete a;  //удаление массива
 
//Задание 2. Вывод слов строки по увеличению количества букв
    printf("Enter your string: ");             //приглашение на ввод строки
    scanf("%359s\n", st);                          //считывание с клавиатуры строки
    printf("\n");
 
    while(strlen(st)>200)                      //защита от дураков
    {
        printf(" You have broken my program \n that was awfully nice of you,try again \n");
        scanf_s("%s",st);
    }
                                                //удаление незначащих пробелов
    for(unsigned int i=0;i<strlen(st);i++)       //узнаем число слов
    {if (st[i]==' ') k++;}
 
    wrds = new int[k];                           //формируем массив, элементы которого - координаты пробелов
    int j=0;
 
    for(unsigned int i=0;i<strlen(st);i++)
        if (st[i]==' ')
        {
            wrds[j]=i;
            j++;        
        }
 
    arw = new word[k];    //массив структур с атрибутами слов
 
    arw[0].b=0;           //заполняем  массив, 1й и последнийй элементы отдельно, остальные в цикле
    arw[0].e=wrds[0]-1;
    arw[0].l=wrds[0]-1;
 
    arw[k-1].b=wrds[k-1];
    arw[k-1].e=strlen(st);
    arw[k-1].l=strlen(st)-wrds[k-1];
 
    for(int i=1;i<k-1;i++)
    {
        arw[i].b=wrds[i]+1;
        arw[i].e=wrds[i+1]-1;
        arw[i].l=arw[i].e-arw[i].b;
    }
    
 
    word buf={0,0,0};      //сортируем массив по убыванию длины слова
    for(int i=0;i<k;i++)
            for( int j=0;j<k;j++)
                if(arw[i].l<arw[j].l)
                {
                    buf.b=arw[i].b;
                    buf.e=arw[i].e;
                    buf.l=arw[i].l;
 
                    arw[i].b=arw[j].b;
                    arw[i].e=arw[j].e;
                    arw[i].l=arw[j].l;
 
                    arw[j].l=buf.b;
                    arw[j].l=buf.b;
                    arw[j].l=buf.b;
                }
 
    printf("Words sorted by decreasing order: \n");  //вывод слов строки по убыванию длины
    for(int i=0;i<k;i++)
    {
        for(int j=arw[i].b;j<arw[i].e;j++)
            printf("%c", st[j]);
        printf("\n");
    }
 
    delete wrds;
    delete arw;
    return 0;
 
}
код подправил, нашел еще несколько косяков, однако появилась проблема - при отладке когда дело доходит до
C++
1
2
3
4
5
6
for(int i=0;i<k;i++)
    {
        for(int j=arw[i].b;j<arw[i].e;j++)
            printf("%c", st[j]);
        printf("\n");
    }
а именно до
C++
1
printf("%c", st[j]);
вылазит следующее:

Необработанное исключение в "0x008c1c07" в "лаб1.exe": 0xC0000005: Нарушение прав доступа при чтении "0xcdfac6c5".

Честно говоря понятия не имею, с чем это может быть связано, похоже на нехорошее разыменование указателей, только как с этим бороться, я не знаю
0
27 / 27 / 6
Регистрация: 27.09.2009
Сообщений: 101
28.10.2013, 15:25 4
Цитата Сообщение от McSimov Посмотреть сообщение
если интересно, то я раскопал, что это можно делать и с помощью scanf в таком виде:
scanf("%359s\n", st);
Я про это знал, просто у меня в VS 2010 это не срабатывает, поэтому и не посоветовал.

Если у вам нужно выполнить это задание на c++,то можно вот так:
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
#include "stdafx.h"
#include <stdlib.h> 
#include <iostream>
#include <algorithm> 
#include <vector>
#include <sstream>
 
using namespace std;
 
bool CompareFunction (string i,string j) 
{ 
    return (i.length()<j.length()); 
}
int main()
{
    char  text[255];
    cin.getline(text,255);
 
    stringstream ss(text);
 
    string s;
    size_t count = 0;
    vector<string> words;
 
    for (; ss >> s; count++)
        words.push_back(s);
 
    sort (words.begin(), words.end(), CompareFunction);
    
    for (int i=0;i<words.size();i++) 
        cout<<words[i]<<"\n";
 
    system("pause");
    return 0;
}
Добавлено через 21 минуту
Ну а по поводу вашего кода:
Посмотрев в отладчике ваш новый код, я не понял как вы не нашли проблемы с вашим алгоритмом, попробуйте поставить много точек останова и посмотреть значения массивов. Приведу часть проблем:
Пример:
Берем строку: 333 1 22. k у нас будет равна 3-м и мы выделяем память под 3-и элемента. Далее вы ищите координаты пробелов и записываете в массив, НО вы не учли тот факт, что пробелов в данной строке 2, а k равна 3-м т.к. вы инициализировали его единицей. В результате этого упущения у вас в массиве wrds адекватные значения только у нулевого и первого элементов. После этого вы создаете массив структур и заполняете первый и последний элементы значениями, НО из-за некорректности последнего элемента в массиве wrds получается, что в этом месте будут не те значения(строки 89-92):
C++
1
2
3
arw[k-1].b=wrds[k-1];
arw[k-1].e=strlen(st);
arw[k-1].l=strlen(st)-wrds[k-1];
Получается в значениях b и l некорректные значения, что в дальнейшем приведет к выходу за диапазон.
1
1 / 1 / 0
Регистрация: 22.10.2013
Сообщений: 17
28.10.2013, 21:55  [ТС] 5
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "stdio.h"
#include "conio.h"
#include "math.h"
#include "string.h"
#include "stdafx.h"
#include <iostream>
 
 
struct word  //пользовательский тип с атрибутами слова в строке - координаты начала и конца и длина
{
    int b,e,l;
};
 
float dist(float a[],int i,int r) //функция вычисления расстояния
{
    float dst=0;
    int end=r;
    
    for(int j=0;j<end ;j++)
        dst+=fabs(a[i]-a[j]);
    return dst;
}
 
 
int _tmain(int argc, _TCHAR* argv[]) 
{
    
    float* a;    //объявление указателя на float
    int n;       //его размер
    float minr=0;  //минимум расстояния
    int minc=0;    //индекс самого близкого к соседям элемента
 
    char st[359];   //исходная строка
    int k=1;          //число слов в строке,изначсально с учетом последнего слова
    int* wrds;      //указатель на int
    word* arw;      //указатель на пользовательский тип
//Задание 1. Поиск элемента с наименьшим расстоянием до других
    printf("Enter number of array elms: ");  //приглашение на ввод количества элементов массива
    scanf_s("%d",  &n);
    printf("\n");                            //считывание с клавиатуры количества элементов
    a = new float[n];                        //динамическое выделение  памяти для массива n элементов
    printf("Fill your array\n");             //заполнение массива
    for(int i=0;i<n;i++)
        scanf_s("%f", &a[i]);
 
    int p=0;
    for(int i=0;i<n;i++)
        if(dist(a,i,n)<dist(a,p,n))
        {
            minr=dist(a,i,n);
            minc=i;
            p=i;
        }
 
    printf("The element # %d has the least distance. The distance is %5.2f\n", minc, minr);
    delete a;  //удаление массива
 
//Задание 2. Вывод слов строки по увеличению количества букв
    printf("Enter your string: \n");             //приглашение на ввод строки
    gets_s(st);                                 //считывание с клавиатуры строки                     
    printf("scaned %s\n ",st);
    printf("\n");
 
    while(strlen(st)>200)                      //защита от дураков
    {
        printf(" You have broken my program \n that was awfully nice of you,try again \n");
        gets_s(st);
    }
                                        
    for(unsigned int i=0;i<strlen(st);i++)       //узнаем число пробелов
    {
        if (st[i]==' ') k++;
    }
    printf("%d",k);
    wrds = new int[k-1];    //выделяем память под массив
                            //формируем массив, элементы которого - координаты пробелов
    int j=0;
    while(j<k-1)
    {
        for(unsigned int i=0;i<strlen(st);i++)
            if (st[i]==' ')
            {
                wrds[j]=i;
                j++;        
            }
    }
    arw = new word[k];    //массив структур с атрибутами слов
 
    arw[0].b=0;           //заполняем  массив, 1й и последний элементы отдельно, остальные в цикле
    arw[0].e=wrds[0]-1;
    arw[0].l=wrds[0];
 
    arw[k-1].b=wrds[k-1]+1;
    arw[k-1].e=strlen(st);
    arw[k-1].l=strlen(st)-wrds[k-1]-1;
 
    j=0;
    for(int i=1;i<k-1;i++)
    {
        arw[i].b=wrds[j]+1;
        arw[i].e=wrds[j+1]-1;
        arw[i].l=arw[i].e-arw[i].b;
        j++;
    }
    
 
    word buf={0,0,0};      //сортируем массив по убыванию длины слова
    for(int i=0;i<k;i++)
            for( int j=0;j<k;j++)
                if(arw[i].l<arw[j].l)
                {
                    buf.b=arw[i].b;
                    buf.e=arw[i].e;
                    buf.l=arw[i].l;
 
                    arw[i].b=arw[j].b;
                    arw[i].e=arw[j].e;
                    arw[i].l=arw[j].l;
 
                    arw[j].b=buf.b;
                    arw[j].e=buf.e;
                    arw[j].l=buf.l;
                }
 
    printf("Words sorted by decreasing order: \n");  //вывод слов строки по убыванию длины
    for(int i=0;i<k;i++)
    {
        for(int j=arw[i].b;j<=arw[i].e;j++)
            printf("%c", st[j]);
        printf("\n");
    }
 
    delete wrds;
    delete arw;
    return 0;
 
}
казалось бы, косяки исправлены и с алгоритмом я разобрался, однако...
при отладке gets_s(st) работает неадекватно, а именно не дает шанса ввести строку. Вот теперь я точно понятия не имею что же, черт возьми, происходит
0
27 / 27 / 6
Регистрация: 27.09.2009
Сообщений: 101
29.10.2013, 15:14 6
К сожалению мой отладчик опять показывает не понятные для меня данные.
Может код вы и изменили, но в массивах осталось всё так же:
В случае с 3-мя словами. Вы заполняете массив wrds двумя элементами(координаты пробелов), допустим тут всё нормально, дальше вы заполняете arw[0] и arw[k-1]. И теперь смотрим дальше: вы сортируете массив из 3-х элементов, но данные в arw[2] снова b и l не корректные, вы отсортировали и выводите. Но при выводе опять выход за диапазон получается. Может я что-то не так делаю, но ваш вариант у меня не работает.
Попробуйте пока отложить ввод строки, а отладить алгоритм. Сделайте так:
C++
1
char st[]="111 2 33";
и проверьте работу.
Мне кажется, что вам лучше заполнять массив arw значениями индексов слов, а не высчитывать через индексы пробелов.
1
29.10.2013, 15:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.10.2013, 15:14
Помогаю со студенческими работами здесь

Вывести все слова строки в порядке убывания
Помогите пожалуйста: Дана строка текста, в которой слова разделены пробелами. Необходимо:...

Вывести на экран слова в порядке возрастания количества букв в них
Дано произвольное предложение. Слова в нём разделены пробелами, а после последнего – точка. Вывести...

Вывести все слова строки в порядке убывания их длин
Дана строка текста, в которой слова разделены пробелами. Необходимо: - определить количество слов...

Дано предложение. Расположить слова в порядке возрастания числа букв в них
Помогите пожалуйста с задачей: Дано предложение. Расположить слова в порядке возрастания числа букв...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru