Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
McSimov
0 / 0 / 0
Регистрация: 22.10.2013
Сообщений: 17
#1

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

25.10.2013, 18:50. Просмотров 888. Ответов 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
#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 минуты
Забыл сказать, что при запуске программы после работы с первой частью программы, верно выводится приглашение на ввод строки, после чего сразу заключительная фраза и программа завершается
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.10.2013, 18:50     Вывести слова строки в порядке убывания числа букв в них
Посмотрите здесь:

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

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

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

Переставить слова в строке в порядке убывания количества цифр в них - C++
Дан текст. Слова в строках переставить в порядке убывания количества цифр в них. как можно реализовать, подскажите пожалуйста. Хотя бы...

Вывести слова в порядке убывания их длин - C++
Дано предложение состоящее только из букв латинского алфавита с нижним и (или) верхним регистром букв. Вывести слова в порядке убывания их...

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

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vivo
23 / 23 / 2
Регистрация: 27.09.2009
Сообщений: 101
25.10.2013, 20:06     Вывести слова строки в порядке убывания числа букв в них #2
Я бы читал строку с помощью gets, так как вроде scanf считает до первого разделителя(пробел тоже разделитель). И у вас в 77 строке цикл до k, но там ведь вы по логике должны пробегать по всей строке(ища координаты пробелов), а получается только по найденному количеству пробелов, что не соответствует длине строки. Так же надо учитывать, что можно ввести несколько пробелов и учитывать,что после последнего слова будет пробел ну и т.д.
McSimov
0 / 0 / 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".

Честно говоря понятия не имею, с чем это может быть связано, похоже на нехорошее разыменование указателей, только как с этим бороться, я не знаю
Vivo
23 / 23 / 2
Регистрация: 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 некорректные значения, что в дальнейшем приведет к выходу за диапазон.
McSimov
0 / 0 / 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) работает неадекватно, а именно не дает шанса ввести строку. Вот теперь я точно понятия не имею что же, черт возьми, происходит
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.10.2013, 15:14     Вывести слова строки в порядке убывания числа букв в них
Еще ссылки по теме:

Ввести 3 числа, вывести на экран в порядке убывания - C++
Пользователь должен ввести 3 числа,а на экран выводятся эти числа в порядке убывания.Как это сделать циклами?

Вывести все целые числа, рассположенные между заданными числами, включая сами эти числа, в порядке их убывания - C++
Даны два целых числа А и B (A&lt;B). Вывести все целые числа, рассположенные между данными числами(включая сами эти числа), в порядке их...

Вывести числа в порядке убывания, вычислить площадь треугольника - C++
Проверить задачу если возможно - собственно прошу вас посмотреть эту задачу. Условие: Ввести три числа. Если они могут быть длинами...

Вывести в порядке убывания все целые числа, расположенные между A и B - C++
1.частное от деления нацело,а также остаток от этого деления. Даны целые положительные числа N и K. Используя только операции сложения и...

Вывести в порядке убывания все целые числа заданного интервала - C++
3. Данные два целых числа А и В (А &lt; В). Вывести в порядке убывания все целые числа, расположенные между А и В (не включая числа А и В), а...

Вывести в порядке убывания все целые числа, расположенные между A и B - C++
Даны два целых числа A и B (A &lt; B). Вывести в порядке убывания все це-лые числа, расположенные между A и B (не включая числа A и B), а...


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

Или воспользуйтесь поиском по форуму:
Vivo
23 / 23 / 2
Регистрация: 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 значениями индексов слов, а не высчитывать через индексы пробелов.
Yandex
Объявления
29.10.2013, 15:14     Вывести слова строки в порядке убывания числа букв в них
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru