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

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

Восстановить пароль Регистрация
 
McSimov
0 / 0 / 0
Регистрация: 22.10.2013
Сообщений: 17
25.10.2013, 18:50     Вывести слова строки в порядке убывания числа букв в них #1
Собственно, имеется готовая на половину программа:

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++ Вывести слова в порядке убывания количества символов
Вывести в порядке убывания все целые числа, расположенные между A и B C++
Вывести в порядке убывания все целые числа, расположенные между A и B C++
Вывести числа в порядке убывания, вычислить площадь треугольника C++
C++ Вывести все слова строки в порядке убывания
Переставить слова в строке в порядке убывания количества цифр в них C++
C++ Ввести 3 числа, вывести на экран в порядке убывания
Вывести в порядке убывания все целые числа, расположенные в заданном диапазоне C++
C++ Вывести в порядке убывания все целые числа заданного интервала
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) работает неадекватно, а именно не дает шанса ввести строку. Вот теперь я точно понятия не имею что же, черт возьми, происходит
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     Вывести слова строки в порядке убывания числа букв в них
Ответ Создать тему
Опции темы

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