Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вырезать из строки целые и вещественные числа 
V
    Опции темы
Vokunya
Дата 23.3.2010, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.12.2008
Где: Беларусь

Репутация: нет
Всего: 1



Поиск дает много чего по такого рода примерам: из, например, "hfuh7jho87jan23" вытащить все числа. Здесь все понятно.
Я стопорюсь с такой задачей:
Дана строка, содержащая слова, целые и вещественные числа. Переставить элементы строки так, чтобы сначала располагались целые числа, потом слова, а потом вещественные числа

Т.е., например: из "16.2 jdfjfsff 45 76jhsk 74.2" получить "45 jdfjfsff 76jhsk 16.2 74.2"
Мои умозаключения сводились к следующему:
1. Разбиваем строку при помощи strtok;
2. Как-то надо узнать что мы получили: целое или вещественное число, или просто слово... я придумал только такое, на мой взгляд, извращение:  smile 
Код

 oneWord = strtok (str, sprs);
    while (oneWord)
    {
        sscanf (oneWord, "%d", &tmpInt);
        sprintf (st, "%d", tmpInt);
        if (strlen (oneWord) == strlen (st))
...

т.е конвертнули слово в int, затем обратная операция, сравнили длину исходного слова и получившегося после конвертирования, если длины равны - то целое число ))
затем аналогичные действия для float, а то что осталось - просто слова 

Вопрос: есть другие решения или мой вариант вполне жизнеспособен?  smile 

PM MAIL ICQ   Вверх
djamshud
Дата 23.3.2010, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Самое верное на мой взгляд решение - написать элементарнейший парсер из десяти строк: разбить строку на поток лексем "слово", "целое", "дробное"" и потом расставить их в нужном порядке.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
GoldFinch
Дата 23.3.2010, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



используйте регулярные выражения.
PM MAIL ICQ   Вверх
Vokunya
Дата 24.3.2010, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.12.2008
Где: Беларусь

Репутация: нет
Всего: 1



Цитата

разбить строку на поток лексем "слово", "целое", "дробное"

я же и интересуюсь реализацией этой задачи  smile 

Цитата

используйте регулярные выражения

хм... даже не задумывался над этим  smile  завтра почитаю что-нибудь, т.к. совсем не имею опыта работы с регэкспами.

Это сообщение отредактировал(а) Vokunya - 24.3.2010, 00:06
PM MAIL ICQ   Вверх
GoldFinch
Дата 24.3.2010, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



хотя регулярки это пожалуй сложновато для такой задачи,
проще перебирать символы в слове и проверять их на "0"-"9" для целых и "." для вещественных

PM MAIL ICQ   Вверх
Vokunya
Дата 24.3.2010, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.12.2008
Где: Беларусь

Репутация: нет
Всего: 1



Цитата

проще перебирать символы в слове и проверять их на "0"-"9" для целых и "." для вещественных

вероятно да

Цитата

регулярки это пожалуй сложновато для такой задачи

но регулярки теперь уже интересны для саморазвития smile  может есть какие-нибудь ресурсы по регулярным выражениям в си, а то беглый просмотр гугла что-то вразумительных результатов не дал

эээ... я плохо смотрел или в стандарте С99 нет библиотеки для регэкспов?

Это сообщение отредактировал(а) Vokunya - 24.3.2010, 09:47
PM MAIL ICQ   Вверх
Earnest
Дата 24.3.2010, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Я бы использовала функцию strtod (хотя не уверена, что она стандартная, но вроде да). Фокус в том, что она возвращает кроме смого числа указатель на место в строке, где ее парсинг закончился (т.е. где число закончилось). Оттуда и нужно начинать следующий парсинг. Можно вообще не париться с анализом - вернула указатель туда же откуда начала - стало быть не число. Но можно сначала сканировать и искать первый символ, который может быть числом. Самому написать, конечно, можно, но  коррекстно распарсить все варианты double - упаришься - все это E-04 и т.д.


--------------------
...
PM   Вверх
xvr
Дата 24.3.2010, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Earnest @ 24.3.2010,  09:47)
Я бы использовала функцию strtod

+1
Добавлю к рекомендации - использовать ее вместе с strtol. Если strtod отработала успешно, на это же слово запускается strtol. Если она вернет тот же поинтер в качестве конца парсинга, то число целое, иначе вещественное

PM MAIL   Вверх
GoldFinch
Дата 24.3.2010, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



вместо С99 проще использовать язык более подходящий для задач связанных с обработкой текста %)
PM MAIL ICQ   Вверх
Earnest
Дата 24.3.2010, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



xvr, точно, чтобы совсем самому не напрягаться smile 


--------------------
...
PM   Вверх
azesmcar
Дата 24.3.2010, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(GoldFinch @  24.3.2010,  11:05 Найти цитируемый пост)
вместо С99 проще использовать язык более подходящий для задач связанных с обработкой текста %) 

дай угадаю.. питон? smile 
PM   Вверх
GoldFinch
Дата 24.3.2010, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



azesmcar, не обязательно.
я бы сделал макрос для ворда или notepad++

PM MAIL ICQ   Вверх
Vokunya
Дата 24.3.2010, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.12.2008
Где: Беларусь

Репутация: нет
Всего: 1



Цитата

вместо С99 проще использовать язык более подходящий для задач связанных с обработкой текста %)

это же задание контрольной работы - только С99  smile 

Earnest, xvr сейчас на скорую руку набросал код с использованием strtod и strtol... вроде парсит  smile 
сейчас нет времени, но сегодня вечером/завтра отпишусь о результатах 
PM MAIL ICQ   Вверх
Vokunya
Дата 24.3.2010, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.12.2008
Где: Беларусь

Репутация: нет
Всего: 1



Итак, в результате наваял вот это:
Код

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(int argc, char * argv [])
{

    //исходное предложение
    char   sentence [101];
    //слово, полученное в результате работы strtok
    char * word;
    //массив символов-разделителей 
    char seps[] = " ,";
    //вторые аргументы для strtod и strtol
    char * endptrDbl;
    char * endptrInt;

    //числа, полученные в результате работы strtod и strtol
    double dblWord;
    int intWord;

    //массивы для хранения уже обработанных word
    char   intPart [101] ="";
    char  dblPart [101] = "";
    char  charPart [101] = "";


    printf ("Input the sentence:\n");
    gets(sentence);

    word = strtok(sentence, seps);
    while (word)
    {
        //если преобразование удалось и преобразованы все символы, которые есть в word
        if ( (dblWord = strtod(word, &endptrDbl)) != 0 && (*endptrDbl == '\0'))
        {
            //над этим же word работает уже strtol
            intWord = strtol (word, &endptrInt, 10);
            //если strtol вернула тот же указатель конца парсига, что и strtod то число целое
            if (endptrDbl == endptrInt)
            {
                //записываем число в предназначенный массив
                strcat(intPart, word);
                strcat(intPart, " ");
            }
            //в противном случае число вещественное
            else
            {
                strcat (dblPart, word);
                strcat (dblPart, " ");
            }
        }
        // если же преобразование не удалось либо обработаны не все символы в word, то это слово
        else
        {
            strcat (charPart, word);
            strcat (charPart, " ");
        }

        word = strtok (NULL, seps);
    }

    sentence [0] = '\0';
    puts ("\nResult sentence:");
    strcat(sentence, intPart);
    strcat(sentence, charPart);
    strcat(sentence, dblPart);
    puts (sentence);

    return 0;
}



Наверняка что-нибудь можно подправить, буду благодарен за предложения!
PM MAIL ICQ   Вверх
Dov
Дата 26.3.2010, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Вот такое предложение:
Код
#define SIZE 101
#define CHARSET "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"

int main(int argc, char * argv [])
{    
    char   sentence[SIZE] = "";   // исходное предложение
    char   intPart [SIZE] = "";   // массивы для хранения уже обработанных word
    char   dblPart [SIZE] = "";    
    char   charPart[SIZE] = "";     
    char   seps[]         = " ,\n"; // массив символов-разделителей
    char * word;                  // слово, полученное в результате работы strtok
    
    printf ("Input the sentence:\n");
    fgets(sentence, SIZE, stdin);
    
    word = strtok(sentence, seps);
    while (word)
    {
        if (strpbrk(word, CHARSET))
            sprintf(charPart + strlen(charPart), "%s ", word);
        else if(strchr(word, '.'))
            sprintf(dblPart + strlen(dblPart), "%s ", word);
        else
            sprintf(intPart + strlen(intPart), "%s ", word);
        
        word = strtok (NULL, seps);
    }
    
    sprintf(sentence, "\nResult sentence:\n%s%s%s", intPart, charPart, dblPart);
    puts (sentence);
    
    return 0;
}


Это сообщение отредактировал(а) Dov - 26.3.2010, 13:55


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0990 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.