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

Поиск слов в строке - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.86
Gepar
 Аватар для Gepar
1173 / 529 / 20
Регистрация: 01.07.2009
Сообщений: 3,511
15.07.2011, 22:59     Поиск слов в строке #1
Пытаюсь тут получить все слова в строке ориентируясь на пробелы, но что-то плохой у меня алгоритм получается, поправьте пожалуйста. Мой криво работающий алгоритм:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    string str,str2;
    cout<<"Enter string: ";
    getline(cin,str);
    int temp=0;
    do
    {
        str2=str.substr(temp,str.find(' ',temp+1));
        temp=str.find(' ',temp+1);
        cout<<endl<<str2;
 
    }while(temp!=-1);
 
}
Если быть точным то проблема заключается в том чтобы правильно хранить последнее вхождение пробела и каждый раз потом при поиске следующего пропускать этот ранее найденный пробел . Хотя у меня из-за кривого поиска в итоге в строку копируется фиг знает что. Просьба помочь.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2011, 22:59     Поиск слов в строке
Посмотрите здесь:

Поиск заданной буквы в строке. Определения количества слов C++
Поиск слов в строке состоящей из русских символов. C++
Поиск количества слов строке(как можно проще) C++
C++ В заданной строке определить количество слов (в строке может содержаться несколько пробелов подряд).
Cтрока: Определить количество средних слов в строке и какое из слов начинается на большую по коду букву C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
15.07.2011, 23:22     Поиск слов в строке #2
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 <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <iterator>
 
int main()
{
    std::string input_string;
 
    std::cout << "Enter string: ";
    std::getline(std::cin, input_string);
 
    std::istringstream istr(input_string);
 
    std::vector< std::string > words;
    std::string word;
 
    while (istr >> word)
        words.push_back(word);
 
    std::copy(words.begin(), words.end(), std::ostream_iterator< std::string > (std::cout, "\n"));
 
    return 0;
}
nameless
Эксперт C++
 Аватар для nameless
289 / 288 / 14
Регистрация: 16.06.2009
Сообщений: 486
15.07.2011, 23:36     Поиск слов в строке #3
Gepar,

Поправил Ваш вариант..

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#include <iostream>
 
int main()
{
   std::string str = "this my test string sbgj";
   std::string tmp;
 
   std::string::size_type pos_start = 0, pos_end;
 
   do
   {
      pos_end = str.find(' ', pos_start);
      tmp = str.substr(pos_start, pos_end - pos_start);
      pos_start = pos_end;
      pos_start++;
      std::cout << tmp << std::endl;
   }
   while (pos_end != std::string::npos);
 
   return 0;
}
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
16.07.2011, 04:40     Поиск слов в строке #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Gepar, просто из любопытства: а зачем Вам это? У silent_1991 в примере никаких заморочек по поводу пробелов и их количества - чем плохо? Вот ещё кстати вариант, чуть по-другому:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>
 
int main(){
    std::string str;
    
    while ( std::cout << "String: " && std::getline(std::cin, str) && ! str.empty() ){
        std::istringstream ist(str);
        std::vector<std::string> vec;
        std::copy(std::istream_iterator<std::string>(ist), std::istream_iterator<std::string>(), std::back_inserter(vec));
        std::cout << "By words:" << std::endl;
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    }
    
    return 0;
}
nameless, это хорошо, когда между словами точно по одному пробелу, а если
C++
1
std::string str = "this   my   test   string   sbgj";
получится
Код
$ ./nameless_by_words
this


my


test


string


sbgj
А если пробелы табуляцией заменить - вообще беда... Короче, или ещё думать, или использовать стандартные средства и голову себе не морочить...
nameless
Эксперт C++
 Аватар для nameless
289 / 288 / 14
Регистрация: 16.06.2009
Сообщений: 486
16.07.2011, 12:13     Поиск слов в строке #5
easybudda,

С учетом Ваших замечаний

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
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
 
void SplitString(std::string str, std::string delims, std::vector <std::string> & vec)
{
 
    std::string::size_type pos_begin = 0, pos_end = 0;
 
    do
    {
        pos_end = str.find_first_of(delims, pos_end + 1);
        if (delims.find(str[pos_begin]) == std::string::npos)
            vec.push_back(str.substr(pos_begin, pos_end - pos_begin));
        pos_begin = pos_end;
        pos_begin++;
    }
    while (pos_end != std::string::npos);
}
 
int main()
{
   std::string str = "Word of sent, dkngj djkbbg    ... Hello, world.! sjkbdgb hdvfvdgvfvdgvfg";
   std::string delims = " ,\n.!";
   std::vector <std::string> v_str;
 
   SplitString(str, delims, v_str);
 
   std::copy(v_str.begin(), v_str.end(), std::ostream_iterator <std::string>(std::cout, "\n"));
 
   return 0;
}
Добавлено через 1 минуту
Хотя лучше не извращаться, а юзать тот же boost::split.
Gepar
 Аватар для Gepar
1173 / 529 / 20
Регистрация: 01.07.2009
Сообщений: 3,511
16.07.2011, 16:20  [ТС]     Поиск слов в строке #6
easybudda, я ещё не сильно с итераторами и потоками строк наловчился манипулировать. Вообще задание подразумевает находить слова которые читаются с обоих концов одинаково, получилось в итоге как-то так:
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
int main()
{
    string str,str2;
    cout<<"Enter string: ";
    getline(cin,str);
    string:: size_type start=0,end;
    cout<<endl<<"Palindromes: ";
 
    do
    {
        end=str.find(' ',start);
        str2=str.substr(start,end-start);
        start=end;
        start++;
        int flag=1;
        int l=str2.size()-1;
        for(int i=0;i<l;i++)
        {
            if (str2[i]!=str2[l-i])
            {
                flag=0;
                break;
            }
 
        }
        if (flag)
         cout<<str2<<" ";
 
        str2="";
 
    }while(end!=string::npos);
 
}
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
16.07.2011, 16:28     Поиск слов в строке #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
26
27
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <iterator>
 
int main()
{
    std::string input_string;
 
    std::cout << "Enter string: ";
    std::getline(std::cin, input_string);
 
    std::istringstream istr(input_string);
 
    std::vector< std::string > palindromes;
    std::string word;
 
    while (istr >> word)
        if (word == std::string (word.rbegin(), word.rend()))
            palindromes.push_back(word);
 
    std::cout << "Palindromes:" << std::endl;
    std::copy(palindromes.begin(), palindromes.end(), std::ostream_iterator< std::string > (std::cout, "\n"));
 
    return 0;
}
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
16.07.2011, 17:37     Поиск слов в строке #8
Если вдруг понадобится искать полиндромы без учета регистра, то можно так:
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
#include <iostream>
#include <string>
 
class ichar_traits:public std::char_traits<char>{
public:
    static int compare(const char *a, const char *b, size_t n){
        for(size_t i=0;i<n;i++){
            if(a==0)
                return -1;
            else if(b==0)
                return 1;
            else if(tolower(*a)<tolower(*b))
                return -1;
            else if(tolower(*a)>tolower(*b))
                return 1;
            ++a;
            ++b;
        }
        return 0;
    }
};
 
typedef std::basic_string<char,ichar_traits> string;
 
std::istream& operator>>(std::istream &in,string& s){// тут пришлось бы писать сложную реализацию, поэтому сделал так коряво)
    std::string ss(s.c_str());
    in>>ss;
    s=ss.c_str();
    return in;
}
 
std::ostream& operator<<(std::ostream &out,string s){
    return out<<s.c_str();
}
 
int main(){
    string word;
        std::cout << "Enter word: ";
    std::cin>>word;
    if (word == string (word.rbegin(), word.rend()))
          std::cout << "Palindromes" << std::endl;
    else std::cout<<"No palindromes"<<std::endl;
    return 0;
}
Чтоб подогнать это все под, например, код silent_1991, то понадобится еще кое что дописать. Но дело не в этом, просто читаю умную книгу (умнею, блин)), вот решил поделится таким вот интересным варинтом, на тему :"извращаемся над string'ами" ))
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
16.07.2011, 17:46     Поиск слов в строке #9
Если без учёта регистра, то можно ещё так:

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 <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
 
bool is_palindrome_reg(std::string word)
{
    std::transform(word.begin(), word.end(), word.begin(), tolower);
 
    return word == std::string (word.rbegin(), word.rend());
}
 
int main()
{
    std::string input_string;
 
    std::cout << "Enter string: ";
    std::getline(std::cin, input_string);
 
    std::istringstream istr(input_string);
 
    std::vector< std::string > palindromes;
    std::string word;
 
    while (istr >> word)
        if (is_palindrome_reg(word))
            palindromes.push_back(word);
 
    std::cout << "Palindromes:" << std::endl;
    std::copy(palindromes.begin(), palindromes.end(), std::ostream_iterator< std::string > (std::cout, "\n"));
 
    return 0;
}
Добавлено через 20 секунд

Не по теме:

Kastaneda, а что за умная книжка?))

Kastaneda
16.07.2011, 17:50
  #10

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение
Если без учёта регистра, то можно ещё так:
Я ж говорю, извращенный способ))

Цитата Сообщение от silent_1991 Посмотреть сообщение
Kastaneda, а что за умная книжка?))
"Философия С++" 2-ой том. Я ее давно еще начинал читать, потом понял, что базовых знаний не хватает и отложил до лучших времен. Вот теперь эти времена настали)

Net_Wanderer
235 / 208 / 19
Регистрация: 08.06.2011
Сообщений: 467
16.07.2011, 20:07     Поиск слов в строке #11
Цитата Сообщение от Gepar Посмотреть сообщение
Вообще задание подразумевает находить слова которые читаются с обоих концов одинаково
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
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
 
#define MAX_STR_LEN 512
#define DELIM " \t\n.,:;""''(){}?!"
 
int main()
{
    char buf[MAX_STR_LEN];
    char *word;
    char *rev;
 
    printf("Enter a string: ");
    fgets(buf, MAX_STR_LEN, stdin);
 
    printf("Palindromes: \n");
 
    for (word = strtok(buf, DELIM);
        word != NULL;
        word = strtok(NULL, DELIM))
    {
        for (size_t i = 0; i < strlen(word); ++i)
            word[i] = tolower(word[i]);
 
        if ((rev = strdup(word)) == NULL) {
            fputs("Can't allocate memory\n", stderr);
            exit(1);
        }
        int result = strcmp(word, strrev(rev));
        free(rev);
        if (! result)
            printf("%s\n", word);
    }
    exit(0);
}
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
16.07.2011, 20:47     Поиск слов в строке #12
немного проще
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <string.h>
#include <ctype.h>
 
#define DELIM " \t\n"
 
int upsidedown(const char * buf, int len){
    return ( len < 2 ) ? 1 : ( toupper(*buf) == toupper(*(buf + len - 1)) ) ? upsidedown(buf + 1, len - 2) : 0;
}
 
int main(void){
    char buf[BUFSIZ], * p;
    
    while ( printf("\nString: ") && fgets(buf, BUFSIZ, stdin) && *buf != '\n' && printf("Palindromes (if any):\n") )
        for ( p = strtok(buf, DELIM); p; p = strtok(NULL, DELIM) )
            if ( upsidedown(p, strlen(p)) )
                printf("%s\n", p);
    
    return 0;
}
Цитата Сообщение от Net_Wanderer Посмотреть сообщение
strrev(rev)
Привет Гейтсу, нет такого в стандарте...
Gepar
 Аватар для Gepar
1173 / 529 / 20
Регистрация: 01.07.2009
Сообщений: 3,511
16.07.2011, 21:24  [ТС]     Поиск слов в строке #13
Цитата Сообщение от easybudda Посмотреть сообщение
немного проще
Лично для меня оно не проще выглядит, а скорее наоборот
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.07.2011, 21:56     Поиск слов в строке
Еще ссылки по теме:

C++ Массив символов (Подсчитать количество слов в строке, при условии, что в качестве разделителя слов используется один или несколько пробелов)
Количество слов в заданной строке (для каждого из слов) C++
C++ Поиск слов в строке c++

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

Или воспользуйтесь поиском по форуму:
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
16.07.2011, 21:56     Поиск слов в строке #14
Цитата Сообщение от Gepar Посмотреть сообщение
Лично для меня оно не проще выглядит, а скорее наоборот
Оно работает проще, а не выглядит.
Yandex
Объявления
16.07.2011, 21:56     Поиск слов в строке
Ответ Создать тему
Опции темы

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