Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
1

Советы по упрощению кода. Количество слов в строке

19.03.2015, 23:07. Просмотров 494. Ответов 19
Метки нет (Все метки)

Доброго времени суток!
Подскажите, пожалуйста, пути упрощения сией простой программки на подсчет слов в строке

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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
 
int main()
{
    setlocale(LC_CTYPE,"Russian");
    string S; unsigned int count = 1, i = 0;
    cout << "Enter your string." << endl;
    getline(cin,S);
    while (S[i] != '\0')
    {
        if (S[i] == ' ' && i != 0 && S[i + 1] != '\0')
        {
            count++;
        }
        i++;
    }
    cout << "Words number: " << count;
    _getch();
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.03.2015, 23:07
Ответы с готовыми решениями:

Количество слов в заданной строке (для каждого из слов)
дано символьная строка. Слово-последовательность символов между пробелами, не содержащие пробелы...

Cтрока: Определить количество средних слов в строке и какое из слов начинается на большую по коду букву
Определить количество средних слов в строе и какое из слов начинается на большую по коду букву. ...

В заданной строке определить количество слов (в строке может содержаться несколько пробелов подряд).
В заданной строке определить количество слов (в строке может содержаться несколько пробелов подряд).

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

19
925 / 625 / 293
Регистрация: 26.02.2015
Сообщений: 2,876
19.03.2015, 23:12 2
Даже не знаю. Можешь переменную i объявить внутри цикла. Тогда по выходу из цикла она освободит немного памяти.

Добавлено через 1 минуту
Кстати, если в строку исходную написать два пробела подряд, то он посчитает это за слово.

Добавлено через 55 секунд
А если 3 пробела написать, то 2 слова будет и т.д. по нарастающей.
1
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
19.03.2015, 23:13  [ТС] 3
Nishen, упс, исправим) А как объявить i в цикле, если в условии нужно указать индекс строки?(S[i])
0
925 / 625 / 293
Регистрация: 26.02.2015
Сообщений: 2,876
19.03.2015, 23:14 4
Цитата Сообщение от misesin Посмотреть сообщение
А как
А никак. Это я не подумал.
0
21 / 21 / 19
Регистрация: 18.03.2014
Сообщений: 148
19.03.2015, 23:18 5
misesin, по сути задача сводится к пересчету числа пробелов в строке.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
 
int main()
{
    setlocale(LC_CTYPE,"Russian");
    
    string S; 
    int count = 1;
    cout << "Enter your string." << endl;
    getline(cin,S);
 
    for(int i=0; S[i]!='\0'; i++) 
       if (S[i]==' ' || S[i+1]=='\0') count++; 
    
    cout << "Words number: " << count;
    _getch();
    return 0;
}
0
493 / 375 / 136
Регистрация: 27.01.2015
Сообщений: 1,588
19.03.2015, 23:19 6
Цитата Сообщение от Nishen Посмотреть сообщение
А никак. Это я не подумал.
Можно сделать while (1) , а внутри через if проверить это же условие, а потом break;

Хотя нет, тоже бред, сори
0
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
19.03.2015, 23:20  [ТС] 7
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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
 
int main()
{
    setlocale(LC_CTYPE,"Russian");
    string S; unsigned int count = 1, i = 0;;
    cout << "Enter your string." << endl;
    getline(cin,S);
    while (S[i] != '\0')
    {
        if (S[i] == ' ' && i != 0 && S[i + 1] != '\0' 
            && S[i + 1] != ' ' && !isdigit(S[i + 1]))
        {
            count++;
        }
        i++;
    }
    cout << "Words number: " << count;
    _getch();
    return 0;
}
0
925 / 625 / 293
Регистрация: 26.02.2015
Сообщений: 2,876
19.03.2015, 23:23 8
misesin, а если я многоточие введу в конце предложение?
0
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
19.03.2015, 23:24  [ТС] 9
bogdan_017, а если введём 2 пробела подряд либо пробелы в конце и в начале либо цифры

Добавлено через 27 секунд
Nishen, а что с многоточием?)

Добавлено через 1 минуту
Nishen, мы ведь пробел перед ним не ставим, как и перед всеми знаками, хотя с другой стороны, мы то не поставим, а кто-то может поставить)
0
925 / 625 / 293
Регистрация: 26.02.2015
Сообщений: 2,876
19.03.2015, 23:25 10
Да, я не то сказать хотел. Вдруг я перед знаком препинания поставлю пробел?
0
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
19.03.2015, 23:28  [ТС] 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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
 
int main()
{
    setlocale(LC_CTYPE,"Russian");
    string S; unsigned int count = 1, i = 0;;
    cout << "Enter your string." << endl;
    getline(cin,S);
    while (S[i] != '\0')
    {
        if (S[i] == ' ' && i != 0 && S[i + 1] != '\0' 
            && S[i + 1] != ' ' && !isdigit(S[i + 1]) 
            && !ispunct(S[i+1]))
        {
            count++;
        }
        i++;
    }
    cout << "Words number: " << count;
    _getch();
    return 0;
}
Добавлено через 1 минуту
Упростили код, называется)

Добавлено через 50 секунд
патч 1.0.3
0
21 / 21 / 19
Регистрация: 18.03.2014
Сообщений: 148
19.03.2015, 23:36 12
misesin, можно юзать тот же код, что я предложил, только в условном операторе несколько дизъюнкций добавить
0
Форумчанин
Эксперт CЭксперт С++
8160 / 5008 / 1436
Регистрация: 29.11.2010
Сообщений: 13,458
19.03.2015, 23:40 13
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
#include <sstream>
 
int main()
{
    std::string S;
    std::cout << "Enter your string.\n";
    std::getline(std::cin, S);
 
    unsigned int counter = 0;
    std::istringstream ist(S);
    for (std::string word; ist >> word; counter++);
 
    std::cout << "Words number: " << counter;
}
0
33 / 33 / 18
Регистрация: 15.05.2013
Сообщений: 236
20.03.2015, 00:15 14
misesin, ты же не решил задачу. А как же:
C++
1
" ,.\"!?:;"
0
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
20.03.2015, 01:29  [ТС] 15
Kant, ispunct(S[i+1] разве не решает проблему?
1
33 / 33 / 18
Регистрация: 15.05.2013
Сообщений: 236
20.03.2015, 05:02 16
Ого! Я не знал такой функции. Спасибо!
Если вбить пустую строку посчитает одно слово и если вбить так:
C++
1
S = "     Grandma!  I  remember  her birth.";
Посчитает 6 слов.

Я делал недавно подсчет всех слов и вывод их в файл.

Добавлено через 12 минут
Убрал лишние. Это С++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
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <algorithm>
 
using namespace std;
 
typedef pair<string, long long> word_numb;
 
map<string, long long> split(const string& str, const string& delimiters);
vector<word_numb> numberOfIdenticalWords(const string& str);
 
long long substr_count_word(const string& haystack, const string& needle);
 
 
int main(int argc, char *argv[])
{
    string DIR = "D:\\1.txt";
    ifstream fin(DIR);
 
    string str((istreambuf_iterator<char>(fin)),
             istreambuf_iterator<char>());
 
    vector<word_numb> wn = numberOfIdenticalWords(str);
    ofstream fout("D:\\number_of_identical_words.txt");
    for(auto i : wn)
        fout << i.first << " " << i.second << endl;
 
    return 0;
}
 
 
map<string, long long> split(const string& str, const string& delimiters) {
    size_t lastPos = str.find_first_not_of(delimiters, 0);
    size_t pos = str.find_first_of(delimiters, lastPos);
 
    map<string, long long> tokens;
    while (string::npos != pos || string::npos != lastPos) {
        string token = str.substr(lastPos, pos - lastPos);
        tokens[token]++;
        lastPos = str.find_first_not_of(delimiters, pos);
        pos = str.find_first_of(delimiters, lastPos);
    }
 
    return tokens;
}
 
 
vector<word_numb> numberOfIdenticalWords(const string& str) {
    map<string,long long> words = split(str, " -,.;:!?\r\n\"");
 
    vector<word_numb> vec_words(words.begin(), words.end());
    sort(vec_words.begin(), vec_words.end(),
         [](const word_numb& a, const word_numb& b)->bool {
        return a.second > b.second;
    });
 
    return vec_words;
}
 
long long substr_count_word(const string& str, const string& needle) {
    map<string, long long> words = split(str, " -,.;:!?\r\n\"");
    return words[needle];
}


Добавлено через 6 минут
substr_count_word ещё выпили.

Добавлено через 23 секунды
substr_count_word ещё выпили.

Добавлено через 24 секунды
substr_count_word ещё выпили.
0
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
20.03.2015, 09:46  [ТС] 17
Препод меня с таким кодом не поймёт)
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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
 
int string_num (string S, unsigned int count, unsigned int i)
{
    if (S[i] != ' ' && S[i] != '\0')
        count = 1;
    else
        count = 0;
    if (S[0] != '\0')
    {
        while (S[i] != '\0')
        {
            if (S[i] == ' ' && S[i + 1] != ' ' && S[i + 1] != '\0'
                && !isdigit(S[i + 1]) 
                && !ispunct(S[i+1]))
            {
                count++;
            }
        i++;
        }
        cout << "Words number: " << count << endl;
    }
    else
        cout << "You've entered an empty string" << endl;
    return count;
}
 
int main()
{
    setlocale(LC_CTYPE,"Russian");
    string S; unsigned int count, i = 0;;
    cout << "Enter your string." << endl;
    getline(cin,S);
    string_num(S, count, i);
    _getch();
    return 0;
}
Сходил на пару и в итоге перевёл основную часть в функцию, исправил ошибку с множеством пробелов в конце.

Добавлено через 29 секунд
И вариант пустой строки учел
0
925 / 625 / 293
Регистрация: 26.02.2015
Сообщений: 2,876
20.03.2015, 09:51 18
Цитата Сообщение от misesin Посмотреть сообщение
cout << "Words number: " << count << endl;
Для чего твоя функция информирует пользователя о количестве слов, если она это количество возвращает из функции? Мне кажется, было бы разумнее в основной программе написать:
C++
1
cout << "Words number: " << string_num(string, count, i)
Добавлено через 1 минуту
И зачем ты в функцию передаешь параметрами count и i? Делай это тогда по ссылке или используй локальные переменные функции.
0
710 / 282 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
20.03.2015, 12:08 19
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <algorithm>
#include <iostream>
#include <string>
 
int main() {
  std::string str;
  std::getline( std::cin, str );
 
  auto words_iter = boost::make_split_iterator(str, boost::token_finder( boost::is_any_of(" ,.\"!?:;" )));
  auto words_num = std::distance( words_iter, decltype( words_iter )() );
 
  std::cout << words_num << std::endl;
}
Кто короче?
0
1 / 1 / 0
Регистрация: 13.11.2014
Сообщений: 40
20.03.2015, 22:58  [ТС] 20
Voivoid, ю вин) но для меня пока слишком сложно

Добавлено через 3 минуты
Препод мне сегодня поведал, что в стринг лучше не использовать '\0', а альтернативу не указал. Какие варианты?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.03.2015, 22:58

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Вычыслить количество слов в строке, длинна которых равна 3 символам и вывести их на экран, если же таких слов нет, то выдать об этом сообщение.
Вычыслить количество слов в строке, длинна которых равна 3 символам и вывести их на экран, если же...

Нужны советы по упрощению программы
Всем доброго вечера! Есть пару вопросов. Итак, решал я в маткаде диффур методом коллокаций. Но...

Как рационально подойти к сокращению и упрощению кода?
Добрый день! Прошу подсказать новичку как рационально подойти к сокращению и упрощению...

В строке S записаны слова исходного текста, в отдельной строке S1- одно из слов, которое может быть в строке S (количество букв в S1 не превышает 10)
В строке S записаны слова исходного текста, в отдельной строке S1 - одно из слов, которое может...


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

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

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